Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在SQL Server中插入后触发器中未显示所有记录_Sql_Sql Server_Sql Server 2008 R2 - Fatal编程技术网

在SQL Server中插入后触发器中未显示所有记录

在SQL Server中插入后触发器中未显示所有记录,sql,sql-server,sql-server-2008-r2,Sql,Sql Server,Sql Server 2008 R2,我有一个表表1,其中包含一些数据: 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(

我有一个表
表1
,其中包含一些数据:

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)
)
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
然后我在
表2
上的Insert后创建了一个
触发器:

create table table2
(
    c1 varchar(20),
    c2 varchar(20)
)
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
时,审计表中只显示一条记录。它不会显示所有插入的记录

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

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

触发器在整个操作中触发一次,请将代码更改为:

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

你看到的行为是故意的。sqlserver中的DML触发器 是语句级触发器-它们在 插入/更新/删除/合并,无论有多少行受到影响 通过DML语句。所以你应该把你的逻辑写在触发器里 处理插入/删除表中的多行


针对该表发出的每个insert语句触发一次触发器。表中插入的每一行没有一个。因此,若插入了多行,则触发器定义应该能够处理多行

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

处理此问题的触发器类似于

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

这是完全正常的。为整个操作触发一次点火
插入表2(c1,c2)从表1中选择c1,c2
不是每行。使用内部触发器
插入表2\u审计(c1、c2、审计操作、审计时间戳)选择列。。。从插入你的触发器有一个主要的缺陷,你似乎认为它每行调用一次——事实并非如此。每个语句触发一次触发器,因此如果
INSERT
语句影响25行,则触发一次触发器,但
Inserted
将包含25行。您的代码将在此处选择这25行中的哪一行<代码>从插入的i中选择@c1=i.c1-这是不确定的,您可以得到一行任意行,其他24行都被忽略。你需要重写你的触发器来考虑这一点!