storeProcecdure可以插入触发器吗?

时间:2012-09-05 06:16:17

标签: sql sql-server-2008

SQL Server 2008

我在

上定义了触发器

用于'INSTEAD OF INSERT'的TABLE_A和用于'INSTEAD OF INSERT'的TABLE_B。

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

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

3 个答案:

答案 0 :(得分:0)

存储过程插入会触发

触发器!

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

答案 1 :(得分: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”,因为触发器每个语句只运行一次,而不是每行运行一次。但正如你所看到的,两个触发器都被触发了。

答案 2 :(得分:0)

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

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值,所以最后一直插入。确定一切都结束了。

感谢Every1的帮助。干杯

道歉。 我不打算将它标记为已回答,因为这纯粹是我的错误,但在问题中没有完全提及。