sql >> データベース >  >> RDS >> Sqlserver

テーブルに列を追加してから、トランザクション内で更新します

    GOはT-SQLコマンドではありません。バッチ区切り文字です。クライアントツール(SSM、sqlcmd、osqlなど)はそれを使用して効果的にカットします 各GOでファイルを送信し、個々のバッチをサーバーに送信します。したがって、明らかにIF内でGOを使用することはできません。また、変数がバッチ間でスコープにまたがることを期待することもできません。

    また、 XACT_STATE()<を確認せずに例外をキャッチすることはできません。 / code> トランザクションが運命づけられていないことを確認します。

    IDにGUIDを使用することは、常に少なくとも疑わしいものです。

    NOT NULL制約を使用し、'{00000000-0000-0000-0000-000000000000}'のようなデフォルトの'guid'を提供します また、正しくすることはできません。

    更新:

    • ALTERとUPDATEを2つのバッチに分けます。
    • sqlcmd拡張機能を使用して、エラー時にスクリプトを中断します。これは、sqlcmdモードがオンの場合のSSMS でサポートされています。 、sqlcmdであり、クライアントライブラリでもサポートするのは簡単です: dbutilsqlcmd
    • XACT_ABORTを使用します エラーを強制してバッチを中断します。これは、メンテナンススクリプト(スキーマの変更)で頻繁に使用されます。ストアドプロシージャとアプリケーションロジックスクリプトは、通常、代わりにTRY-CATCHブロックを使用しますが、適切な注意が必要です。例外処理とネストされたトランザクション

    スクリプト例:

    :on error exit
    
    set xact_abort on;
    go
    
    begin transaction;
    go
    
    if columnproperty(object_id('Code'), 'ColorId', 'AllowsNull') is null
    begin
        alter table Code add ColorId uniqueidentifier null;
    end
    go
    
    update Code 
      set ColorId = '...'
      where ...
    go
    
    commit;
    go
    

    成功したスクリプトのみがCOMMITに到達します 。エラーが発生すると、スクリプトとロールバックが中止されます。

    COLUMNPROPERTYを使用しました 列の存在を確認するには、代わりに任意の方法を使用できます(例:lookup sys.columns



    1. ZendDatabase挿入された行の最後のID。 (postgresを使用)

    2. mysqlの2つの日付の間の土曜日と日曜日の総数を計算する方法

    3. postgresqlを使用してタイムスタンプと数値をフォーマットするための2つの質問

    4. 本当にSETXACT_ABORTONを使用する必要がありますか?