1

SQL Server 2008

トリガーを定義しました

'INSTEAD OF INSERT'の場合はTABLE_A、'INSTEADOFINSERT'の場合はTABLE_B。

両方のトリガーは、挿入されたテーブルとのマージを実行します。

TABLE_A挿入はユーザー/コードによって実行され、正常に機能しています。挿入のトリガーが起動されます。

TABLE_ATRIGGER内にプロシージャSP_1を格納しました。

SP_1いくつかの条件に基づいて、TABLE_AからTABLE_Bにデータを挿入します。

ただし、問題は、ストアドプロシージャ(SP_1)がデータを挿入しているときに、TABLE_Bのトリガーが起動されず、データがそのまま挿入されることです。

では、ストアドプロシージャは起動トリガーを挿入できますか?

擬似コード

ALTER TRIGGER [dbo].[trgtable_AInsert] ON [dbo].[TABLE_A]
Instead of INSERT
AS
BEGIN
SET NOCOUNT ON;     

    IF exists(SELECT * FROM INSERTED)
    BEGIN

        MERGE
             .......
             ...........
             ..............

    end

       EXEC SP_1 @employee_id
end

ALTER TRIGGER [dbo].[trgtableB_Insert] ON [dbo].[TABLE_B]
     Instead of INSERT
     AS
     BEGIN
       SET NOCOUNT ON;      
           IF exists(SELECT * FROM INSERTED)
           BEGIN
              MERGE
                 .......
                 ...........
                 ..............
           end
     end

    ALTER PROCEDURE [dbo].[SP_1] @employeeid int
    AS
    BEGIN   
        BEGIN TRANSACTION           

            insert into TABLE_B
                 .......
                 ...........
                 ..............
                from TABLE_A
        where employee_ID is @employeeid
        COMMIT TRANSACTION
   END

4

3 に答える 3

0

はい、トリガーはストアド プロシージャの挿入によって起動できます。

しかし、問題は、この場合INSTEAD OFトリガーの代わりにAFTERを使用しようとする必要があることだと思います。すべてのコードを確認することはできませんが、代わりにトリガーでオーバーライドしたために挿入が行われない可能性があります。AFTER トリガーを使用すると、2 番目のトリガーを起動しても問題はありません。

于 2012-09-05T06:21:31.600 に答える
0

これはコメントには大きすぎ、書式設定が必要なため、「回答」として投稿してください。

はい、この場合、トリガーが起動します。あなたの例を取り、それを少し変更します(ただし、警告に注意してください):

create table Table_A (ID int not null)
go
create table Table_B (ID int not null)
GO
    CREATE PROCEDURE [dbo].[SP_1] @employeeid int
    AS
    BEGIN   
        BEGIN TRANSACTION           

            insert into TABLE_B (ID)
            SELECT ID from TABLE_A
        where ID = @employeeid
        COMMIT TRANSACTION
   END
GO

トリガーの作成:

CREATE TRIGGER [dbo].[trgtable_AInsert] ON [dbo].[TABLE_A]
Instead of INSERT
AS
BEGIN
SET NOCOUNT ON;     

    IF exists(SELECT * FROM INSERTED)
    BEGIN

        MERGE
            into Table_A a
            using inserted i on a.id = i.id
            when not matched then insert (ID) values (i.id);

    end
    --Wrong code, just for example
    declare @employee_id int
    select @employee_id = ID from inserted --BAD CODE, Ignores multiple rows
       EXEC SP_1 @employee_id
end
GO
CREATE TRIGGER [dbo].[trgtableB_Insert] ON [dbo].[TABLE_B]
     Instead of INSERT
     AS
     BEGIN
       SET NOCOUNT ON;      
           IF exists(SELECT * FROM INSERTED)
           BEGIN
              MERGE
                 into Table_B b
                 using inserted i on b.id = i.id
                 when not matched then insert (ID) values (i.id+5);
           end
     end
GO

そして、試行挿入を実行しTable_Aます:

insert into Table_A (ID) values (1),(2)
select * from Table_B

私のマシンでは、現時点では、値が「7」の単一行の最終結果が得られます。トリガーは行ごとに 1 回ではなく、ステートメントごとに 1 回しか実行されないため、このサンプルを実行して結果「6」を取得する人もいます。しかし、ご覧のとおり、両方のトリガーが起動しています。

于 2012-09-05T06:54:24.260 に答える
0

コメント@AndrásOttóで以前に述べたように

Merge
using(... = "column with possible null values" AND 
      ... = ... AND 
      ... = ...
     ) 

のマージが正しく機能せず、レコードが常に挿入されていました。

1 = 1 and E=E and NULL=NULL is not true. (of-course sql 101) 

私はこのコラムを見落としており、値を削除するために where 句を適切に配置しなかったnullため、常に挿入することになりました。すべてが機能することを修正しました。

助けてくれてありがとうEvery1。乾杯

申し訳ありません。質問で完全に言及されていないのは純粋に私の間違いであるため、回答済みとマークするつもりはありません。

于 2012-09-05T07:06:28.380 に答える