未在SQL Server中显示After Insert触发器中的所有记录

时间:2015-09-04 11:36:48

标签: sql sql-server sql-server-2008-r2

我有一张表table1,其中包含一些数据:

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)
)

然后我在After Insert上创建了table2触发器:

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时,在审核表中只显示一条记录。它不显示所有插入的记录。

我使用此查询复制table2中的记录: -

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

2 个答案:

答案 0 :(得分: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 Server中的DML触发器   是语句级触发器 - 它们会被触发一次   INSERT / UPDATE / DELETE / MERGE,无论受影响的行数   通过DML声明。所以你应该在触发器中编写你的逻辑   处理插入/删除表中的多行

答案 1 :(得分:1)

对于针对此表发出的每个插入语句,您的触发器将触发一次。不是每个插入表中的行。因此,如果插入了多行,则触发器定义应该能够处理多行。

不是使用变量从插入的表中捕获值然后将它们插入表2中,而只需从插入的表中选择并将数据插入Table2_audit。

处理此问题的触发器看起来像........

    public void screenShot(string path)
    {
        var bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
                                        Screen.PrimaryScreen.Bounds.Height,
                                        PixelFormat.Format32bppArgb);

        var gfxScreenshot = Graphics.FromImage(bmpScreenshot);
        gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X,
                                    Screen.PrimaryScreen.Bounds.Y,
                                    0,
                                    0,
                                    Screen.PrimaryScreen.Bounds.Size,
                                    CopyPixelOperation.SourceCopy);

        bmpScreenshot.Save(path, ImageFormat.Png);
    }