2015-09-04 41 views
-1

我有一個表table1一些數據:沒有出現在SQL Server中插入觸發後的所有記錄

create table table1 
(
    c1 varchar(20), 
    c2 varchar(20) 
) 

insert into table1 values('1','A') 
insert into table1 values('2','B') 
insert into table1 values('3','C') 
insert into table1 values('4','D') 
insert into table1 values('5','E') 
insert into table1 values('6','F') 

現在我創建具有相同結構的另一個表稱爲table2

create table table2 
(
    c1 varchar(20), 
    c2 varchar(20) 
) 

然後我在table2上創建了After Insert觸發器:

CREATE TRIGGER trgAfterInsert 
ON [dbo].[table2] 
FOR INSERT 
AS 
    declare @c1 varchar(20); 
    declare @c2 varchar(20); 
    declare @audit_action varchar(100); 

    select @c1 = i.c1 from inserted i; 
    select @c2 = i.c2 from inserted i; 

    set @audit_action = 'Inserted Record -- After Insert Trigger.'; 

    insert into table2_Audit(c1, c2, Audit_Action, Audit_Timestamp) 
    values(@c1, @c2, @audit_action, getdate()); 

    PRINT 'AFTER INSERT trigger fired.' 
    GO 

有一個問題,當我將table1的所有數據複製到tabe2然後在審計表中只有一個記錄show.It不顯示所有插入的記錄。

我用這個查詢副本紀錄table2: -

insert into table2(c1,c2) select c1,c2 from table1 
+0

這是完全正常的。爲整個操作觸發一次'insert into table2(c1,c2)從table1中選擇c1,c2不是每行。使用內部觸發器'insert into table2_Audit(c1,c2,Audit_Action,Audit_Timestamp) SELECT cols ... FROM inserted;' – lad2025

+1

您的觸發器具有** MAJOR **缺陷,因爲您似乎認爲它會被稱爲**每行一次** - 這是**不是**的情況。觸發器將在每個語句**中觸發一次**,因此如果您的INSERT語句影響25行,您將觸發**一次**,但是「插入」將包含25行。您的代碼在這25行中選擇哪一個? '從插入的i中選擇@ c1 = i.c1; ' - 它是非確定性的,你得到*一個,任意*行,所有24個被**忽略**。你需要重寫你的觸發器來考慮這個問題! –

回答

1

,您的觸發火災多行。表中插入的每一行都不是一個。因此,如果插入多行,觸發器定義應該能夠處理多行。

不是使用變量從插入的表中捕獲值,然後將它們插入到表2中,只需從插入的表中選擇並將數據插入到Table2_audit中即可。

一個觸發器來處理這個看起來像........

CREATE TRIGGER trgAfterInsert ON [dbo].[table2] 
     FOR INSERT 
     AS 
BEGIN 
    SET NOCOUNT ON; 

    insert into table2_Audit (c1,c2,Audit_Action,Audit_Timestamp) 
    SELECT C1 
     , C2 
     , 'Inserted Record -- After Insert Trigger.' 
     , GETDATE() 
    FROM inserted ; 

PRINT 'AFTER INSERT trigger fired.' 
END 
GO 
1

觸發每整個操作觸發一次,改變你的代碼:

CREATE TRIGGER trgAfterInsert ON [dbo].[table2] 
FOR INSERT 
AS 
BEGIN 
DECLARE @audit_action VARCHAR(100) = 'Inserted Record -- After Insert Trigger.'; 

INSERT INTO table2_Audit(c1,c2,Audit_Action,Audit_Timestamp) 
SELECT i.c1, i.c2, @audit_action, GETDATE() 
FROM inserted i; 

END 

二不使用PRINT內觸發;

More info

您所看到的現象是由設計。 SQL語句中的DML觸發器 是語句級觸發器 - 它們在 INSERT/UPDATE/DELETE/MERGE後被觸發一次,不管有多少行受到影響 由DML語句。所以,你應該寫你的邏輯在觸發 處理插入/刪除表一次針對該表發出的每個插入語句