而不是插入触发器 VS For 在 SQL Server 中插入触发器

wal*_*ari 3 trigger sql-server

编辑:我的问题是因为在而不是关闭插入触发器中有一个插入语句,那么它应该从而不是关闭插入触发器内部调用插入触发器,并且应该避免在测试表中插入行。我的观察是,插入触发器正在触发,但在关闭触发器之后,它已经在可测试中插入了新行。因为插入触发器引发错误,但关闭触发器已经在测试表中插入了一行。为什么不从内部调用插入触发器而不是从插入触发器中调用?

我在名为 TestTable 的表上有两个触发器。一个是代替插入触发器,第二个是插入触发器后。首先而不是插入触发器将触发,然后插入触发器。它在TestTable 和CopyTable 中插入新行,但不在AuditTable 中插入新行。

我的问题是为什么不触发插入触发器而不是触发器?它应该是因为它也在其中使用插入查询。为什么 TestTable 得到新插入的行?

我的表脚本

CREATE TABLE [dbo].[TestTable](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](50) NULL,
    [Age] [int] NULL,
    [DOB] [date] NULL,
    [Address] [nvarchar](50) NULL,
 CONSTRAINT [PK_TestTable] PRIMARY KEY CLUSTERED 
Run Code Online (Sandbox Code Playgroud)

我的 SQL 查询:

Insert into dbo.TestTable values ('Waleed',24,'10-2-2015','Lahore');
Run Code Online (Sandbox Code Playgroud)

我的而不是插入触发器是:

ALTER TRIGGER [dbo].[utInsteadoff]
   ON  [dbo].[TestTable] 
   Instead of Insert
AS 
    Declare @Name as nvarchar(50)
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    Insert into dbo.TestTable (Name,Age,DOB,Address) Select Name,Age,DOB,Address From inserted; 
    Insert into dbo.CopyTable (Id,Name,Age,DOB,Address) Select Id,Name,Age,DOB,Address From inserted;  

END
Run Code Online (Sandbox Code Playgroud)

插入触发器后是:

ALTER TRIGGER [dbo].[insertTrigger] 
   ON  [dbo].[TestTable] 
   AFTER Insert
AS 
 Declare @Name as nvarchar(50)
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;
     Set @Name = (Select Name from inserted)


 If (@Name = 'Waleed')
    Raiserror('You Cannot Enter Waleed Name',10,1)
  Else
 Begin 

    Insert into dbo.AuditTable (ID,Name,Age,DOB,Location)
    Select ID,Name,Age,DOB,Address from inserted
    -- Insert statements for trigger here
end
END
Run Code Online (Sandbox Code Playgroud)

Pau*_*ite 6

我的问题是为什么不触发插入触发器而不是触发器?它应该是因为它也在其中使用插入查询。为什么 TestTable 得到新插入的行?

INSTEAD OF触发器取代了原来的插入。所以代码:

Insert into dbo.TestTable (Name,Age,DOB,Address) 
Select Name,Age,DOB,Address From inserted; 
Run Code Online (Sandbox Code Playgroud)

...被执行而不是原始插入:

Insert into dbo.TestTable values ('Waleed',24,'10-2-2015','Lahore');
Run Code Online (Sandbox Code Playgroud)

在检查约束之前以及在任何触发器触发之前完成代替触发器中的操作AFTER

替代触发器完成时,一行已添加到TestTableCopyTable表中。请注意,此时事务仍处于活动状态,因此更改还不是永久性的。

接下来,后触发器触发。它在插入的表中看到名称“Waleed” ,打印一条消息,但不回滚迄今为止在事务中所做的更改(包括由而不是触发器添加的行)。没有行添加到AuditTable

如果检查名称“Waleed”的条件也执行了回滚,则所有内容都将回滚,并且不会向任何表添加任何行。