2017-02-16 68 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表中的一行 - 這是的情況下,由於觸發器將被稱爲每個語句一次(每行不會一次),因此如果一次插入20行,觸發器被稱爲只有一次,而Inserted僞表包含20行。

因此,這樣的代碼:

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

失敗,因爲你只檢索一個(任意)從Inserted錶行,你會忽略所有其他行可能在Inserted

編程觸發器時需要考慮到這一點!你必須以適當的方式做到這一點,以集合爲基礎的時尚 - 不是一排排苦惱的排!

試試這個代碼:

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

沒有什麼在這個觸發,將處理多重插入/更新語句。您將需要使用一個將處理多個記錄的場景,或者使用IF @@ ROWCOUNT = 1 else語句來檢查有多少記錄受到影響。在你的榜樣,我只想用類似

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

至於您的詳細表格,我看到馬克糾正了自己的答案,包括了多條線路,並有一個簡單的解決方案,也可以創建在tbl_Protocol第二觸發器。我過去使用的另一個解決方案是一個臨時表,用於處理非常複雜的觸發器。