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

SQL Server AFTER INSERT トリガーに、挿入されたばかりの行が表示されない

    トリガーは変更されたデータを変更できません (Inserted または Deleted ) そうしないと、変更によってトリガーが再度呼び出されるため、無限の再帰が発生する可能性があります。 1 つのオプションは、トリガーがトランザクションをロールバックすることです。

    編集: これは、SQL の標準では、挿入および削除された行はトリガーによって変更できないためです。根本的な理由は、変更によって無限再帰が発生する可能性があるためです。一般的なケースでは、この評価には、相互に再帰的なカスケード内の複数のトリガーが含まれる可能性があります。このような更新を許可するかどうかをシステムにインテリジェントに決定させることは、計算上困難であり、本質的には停止問題のバリエーションです。

    これに対する受け入れられた解決策は、トランザクションをロールバックすることはできますが、トリガーが変化するデータを変更することを許可しないことです。

    create table Foo (
           FooID int
          ,SomeField varchar (10)
    )
    go
    
    create trigger FooInsert
        on Foo after insert as
        begin
            delete inserted
             where isnumeric (SomeField) = 1
        end
    go
    
    
    Msg 286, Level 16, State 1, Procedure FooInsert, Line 5
    The logical tables INSERTED and DELETED cannot be updated.
    

    このようなものは、トランザクションをロールバックします。

    create table Foo (
           FooID int
          ,SomeField varchar (10)
    )
    go
    
    create trigger FooInsert
        on Foo for insert as
        if exists (
           select 1
             from inserted 
            where isnumeric (SomeField) = 1) begin
                  rollback transaction
        end
    go
    
    insert Foo values (1, '1')
    
    Msg 3609, Level 16, State 1, Line 1
    The transaction ended in the trigger. The batch has been aborted.
    


    1. モーダルフレームでデータベース値を表示すると、最初のレコードのみが表示されます

    2. 同じテーブルを異なる列で2回結合する

    3. mySQLのクロス集計ビュー?

    4. SQLServerで数値を含まない値を取得する方法