1

SQL Server 2008

我已经定义了触发器

TABLE_A 用于“INSTEAD OF INSERT”,TABLE_B 用于“INSTEAD OF INSERT”。

两个触发器都与插入的表执行合并。

TABLE_A 插入由用户/代码完成并且运行良好,触发插入的触发器。

我在 TABLE_A TRIGGER 中有存储过程 SP_1。

SP_1 根据某些条件将 TABLE_A 中的数据插入 TABLE_B。

但问题是当存储过程 (SP_1) 插入数据时,不会触发 TABLE_B 上的触发器,而是按原样插入数据。

那么存储过程可以插入触发触发器吗?

伪代码

ALTER TRIGGER [dbo].[trgtable_AInsert] ON [dbo].[TABLE_A]
Instead of INSERT
AS
BEGIN
SET NOCOUNT ON;     

    IF exists(SELECT * FROM INSERTED)
    BEGIN

        MERGE
             .......
             ...........
             ..............

    end

       EXEC SP_1 @employee_id
end

ALTER TRIGGER [dbo].[trgtableB_Insert] ON [dbo].[TABLE_B]
     Instead of INSERT
     AS
     BEGIN
       SET NOCOUNT ON;      
           IF exists(SELECT * FROM INSERTED)
           BEGIN
              MERGE
                 .......
                 ...........
                 ..............
           end
     end

    ALTER PROCEDURE [dbo].[SP_1] @employeeid int
    AS
    BEGIN   
        BEGIN TRANSACTION           

            insert into TABLE_B
                 .......
                 ...........
                 ..............
                from TABLE_A
        where employee_ID is @employeeid
        COMMIT TRANSACTION
   END

4

3 回答 3

0

这对于评论来说太大了,需要格式化,因此作为“答案”发布。

是的,在这种情况下触发器会触发。以您的示例并稍作修改(请注意警告):

create table Table_A (ID int not null)
go
create table Table_B (ID int not null)
GO
    CREATE PROCEDURE [dbo].[SP_1] @employeeid int
    AS
    BEGIN   
        BEGIN TRANSACTION           

            insert into TABLE_B (ID)
            SELECT ID from TABLE_A
        where ID = @employeeid
        COMMIT TRANSACTION
   END
GO

创建触发器:

CREATE TRIGGER [dbo].[trgtable_AInsert] ON [dbo].[TABLE_A]
Instead of INSERT
AS
BEGIN
SET NOCOUNT ON;     

    IF exists(SELECT * FROM INSERTED)
    BEGIN

        MERGE
            into Table_A a
            using inserted i on a.id = i.id
            when not matched then insert (ID) values (i.id);

    end
    --Wrong code, just for example
    declare @employee_id int
    select @employee_id = ID from inserted --BAD CODE, Ignores multiple rows
       EXEC SP_1 @employee_id
end
GO
CREATE TRIGGER [dbo].[trgtableB_Insert] ON [dbo].[TABLE_B]
     Instead of INSERT
     AS
     BEGIN
       SET NOCOUNT ON;      
           IF exists(SELECT * FROM INSERTED)
           BEGIN
              MERGE
                 into Table_B b
                 using inserted i on b.id = i.id
                 when not matched then insert (ID) values (i.id+5);
           end
     end
GO

并执行一个试验插入Table_A

insert into Table_A (ID) values (1),(2)
select * from Table_B

目前,在我的机器上,我得到了值为“7”的单行的最终结果。其他人可能会运行此示例并得到结果“6”,因为触发器仅在每个语句中运行一次,而不是在每行中运行一次。但正如您所见,两个触发器都已触发。

于 2012-09-05T06:54:24.260 回答
0

的,触发器可以由存储过程插入触发!

但我认为问题在于在这种情况下您应该尝试使用AFTER而不是INSTEAD OF触发器。因为我看不到你的所有代码,但有可能插入没有完成,因为你在而不是触发器中覆盖了它。使用 AFTER 触发器,触发第二个触发器应该没有问题。

于 2012-09-05T06:21:31.600 回答
0

正如我之前在评论中提到的@András Ottó

Merge
using(... = "column with possible null values" AND 
      ... = ... AND 
      ... = ...
     ) 

合并无法正常工作,并且总是插入记录。

1 = 1 and E=E and NULL=NULL is not true. (of-course sql 101) 

我忽略了这一列,并且没有正确放置 where 子句来删除null值,因此最终一直插入。修复一切最终正常工作。

感谢每个 1 的帮助。干杯

道歉。我不会将其标记为已回答,因为这纯粹是我的错误,问题中没有完全提到。

于 2012-09-05T07:06:28.380 回答