2017-02-16 11 views
1

は、私は3つのテーブルtbl_Userstbl_Protocoltbl_ProtocolDetailsを持っていると私のトリガーの内部Usersに、私はProtocolに挿入し、その後ProtocolDetailsに挿入する必要がありますが、私は、挿入された範囲をどのように動作するか分かりません。そのようなトリガー内から他のテーブルに挿入されたIDを取得する方法は?

何か:

CREATE TRIGGER tg_Users ON tbl_Users 
AFTER INSERT, UPDATE AS 
BEGIN 
    DECLARE @UserId  = Int 
    DECLARE @ProtocolId = Int 
    DECLARE @UserDetail = NVARCHAR(255) 

    SELECT 
     @UserId = user_id, 
     @UserDetail = user_detail + '@' + user_explanation 
    FROM INSERTED 

    INSERT INTO tbl_Protocol (user_id, inserted_date) 
    VALUES (@UserId, GetDate()) 

    -- Return Inserted Id from tbl_Protocol into @ProtocolDetail then 

    INSERT INTO tbl_ProtocolDetails (protocol_id, protocol_details) 
    VALUES (@ProtocolId, @UserDetail) 
END 

答えて

2

あなたのトリガーは、あなたが常にInsertedテーブルに1つだけの行を持つことを期待しているようだという点で、MAJOR欠陥を持っている - それは、以来、ないケースですトリガーは(各行に1回ではありません)に一度にと呼び出されるため、一度に20行を挿入すると、が1回だけInserted疑似テーブルが20行含まれます。

したがって、このようなコード:あなたはInsertedテーブルからのみ(任意)行を取得しますので、

Select @UserId = user_id, 
     @UserDetail = user_detail + '@' + user_explanation 
From INSERTED; 

を失敗し、あなたはその可能性があるすべての他の行を無視しますInsertedにあります。

トリガーをプログラミングする際に考慮する必要があります。あなたは適切な、セットベースのファッションでこれを行う必要があります - 行ごとにagonizing行のstlye!

は、このコードを試してみてください。

CREATE TRIGGER tg_Users ON tbl_Users 
AFTER INSERT, UPDATE AS 
BEGIN 
    -- declare an internal table variable to hold the inserted "ProtocolId" values 
    DECLARE @IdTable TABLE (UserId INT, ProtocolId INT); 

    -- insert into the "tbl_Protocol" table from the "Inserted" pseudo table 
    -- keep track of the inserted new ID values in the @IdTable 
    INSERT INTO tbl_Protocol (user_id, inserted_date) 
     OUTPUT Inserted.user_id, Inserted.ProtocolId INTO @IdTable(UserId, ProtocolId) 
     SELECT user_id, SYSDATETIME() 
     FROM Inserted; 

    -- insert into the "tbl_ProtocolDetails" table from both the @IdTable, 
    -- as well as the "Inserted" pseudo table, to get all the necessary values 
    INSERT INTO tbl_ProtocolDetails (protocol_id, protocol_details) 
     SELECT 
      t.ProtocolId, 
      i.user_detail + '@' + i.user_explanation 
     FROM 
      @IdTable t 
     INNER JOIN 
      Inserted i ON i.user_id = t.UserId 
END 
+1

ありがとう、私はこのデータベースがこの動作を持っているか分からなかった –

0

複数の挿入/更新文を扱うでしょう、このトリガーでは何もありません。複数のレコードを処理する1つのシナリオを使用するか、IF @@ ROWCOUNT = 1 elseステートメントでいくつのレコードが有効になったかを確認する必要があります。あなたの例では、私はちょうどあなたの詳細テーブル用として

insert into tbl_Protocol(user_id, inserted_date) 
select user_id, user_detail + '@' + user_explanation 
From INSERTED; 

のようなものを使用することになり、私は参照マークは複数の行を含めるために彼の答えを修正し、簡単な解決策を持っているか、tbl_Protocolに第2のトリガを作成することができます。過去に私が使用してきたもう一つの解決策は、非常に複雑なトリガーがあるときの一時テーブルです。

関連する問題