我有一张表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
答案 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
;
您所看到的行为是设计上的。 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);
}