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

SQL Server 2008 MERGE ステートメント - INSTEAD OF INSERT トリガーを無効にして MERGE を許可する方法

    クエリ オプティマイザーは T-SQL バッチの静的解析を行い、MERGE ステートメントを確認するとすぐに要件を検証します。 MERGE ステートメントの前にトリガーに影響を与える DDL ステートメントは考慮されません。

    GO を使用してステートメントを個別のバッチに分割することでこれを回避できますが、単一の SP (GO ステートメントなし) にある場合は、2 つの選択肢があります

    • メイン SP が呼び出すサポート SP に MERGE を配置します。または
    • 動的 SQL を使用する

    動的 SQL

    トリガー付きのテーブルを作成しましょう

    create table tg1(i int)
    ;
    create trigger tg1_tg on tg1 instead of insert as 
    select 1
    GO
    

    次に、テーブルで MERGE を試みます

    alter table tg1 disable trigger tg1_tg
    ;
    merge tg1 as target
    using (select 1 union all select 3) as source (X) on target.i = source.x
    when matched then
        delete
    when not matched by target then
        insert (i) values (x)
    output $action, inserted.*, deleted.*
    ;
    alter table tg1 enable trigger tg1_tg
    ;
    

    良くない..

    そこで、動的 SQL を使用します

    alter table tg1 disable trigger tg1_tg
    ;
    exec ('
    merge tg1 as target
    using (select 1 union all select 3) as source (X) on target.i = source.x
    when matched then
        delete
    when not matched by target then
        insert (i) values (x)
    output $action, inserted.*, deleted.*
    ;')
    alter table tg1 enable trigger tg1_tg
    ;
    

    サポート手順

    MERGE を実行するプロシージャを作成しましょう (プロダクション プロシージャには、おそらくテーブル変数があり、#temp テーブルを使用するか、いくつかのパラメーターを使用します)

    create proc tg1_MERGE as
    merge tg1 as target
    using (select 1 union all select 3) as source (X) on target.i = source.x
    when matched then
        delete
    when not matched by target then
        insert (i) values (x)
    output $action, inserted.*, deleted.*
    ;
    GO
    

    いけません...

    作成する場合でも、トリガーを無効にする必要があります。トリガーを無効にして、proc を再度作成します。今回は機能します。

    最後に、動作するこのバッチを実行できます

    alter table tg1 disable trigger tg1_tg
    ;
    exec tg1_MERGE
    ;
    alter table tg1 enable trigger tg1_tg
    ;
    



    1. NULLの複雑さ–パート1

    2. SQLでセルの繰り返し単語を見つける方法

    3. MySqlから取得するJCombobox値

    4. SQL INTERSECT