带有循环的SQL Server触发器,用于多行插入

时间:2017-01-31 00:50:23

标签: sql sql-server tsql database-trigger

我已经为我的数据库创建了触发器来处理一些插入,但是当我在1个SQL查询中添加多个值时,它不起作用:

ALTER TRIGGER [dbo].[ConferenceDayTrigger]
ON [dbo].[Conferences]
AFTER INSERT
AS 
BEGIN
    DECLARE @ID INT
    DECLARE @dayC INT
    DECLARE @counter INT

    SET @counter = 1
    SET @ID = (SELECT  IDConference FROM Inserted)
    SET @dayC = (SELECT   DATEDIFF(DAY, start,finish) FROM Inserted)

    WHILE @counter <= @dayC + 1 
    BEGIN
        EXEC AddConferenceDay @Id, @counter
        SET @counter = @counter +1
    END
END

对于单次插入,它可以正常工作。但是我应该更改/添加什么才能使其为插入值的每一行执行?

3 个答案:

答案 0 :(得分:2)

如果您无法更改存储过程,那么这可能是光标进入救援时的(极少数)情况之一。实际上是双循环:

ALTER TRIGGER [dbo].[ConferenceDayTrigger]
ON [dbo].[Conferences]
AFTER INSERT
AS 
BEGIN
     DECLARE @ID INT;
     DECLARE @dayC INT;
     DECLARE @counter INT
     SET @counter = 1;

     DECLARE yucky_Cursor CURSOR FOR
        SELECT IDConference, DATEDIFF(DAY, start,finish) FROM Inserted; 
     OPEN yucky_Cursor; /*Open cursor for reading*/


     FETCH NEXT FROM yucky_Cursor INTO @ID, @dayC;
     WHILE @@FETCH_STATUS = 0 
     BEGIN
         WHILE @counter <= @dayC + 1
         BEGIN
             EXEC AddConferenceDay @Id, @counter;
             SET @counter = @counter + 1;
         END;
         FETCH NEXT FROM yucky_Cursor INTO @ID, @dayC;
     END;

    CLOSE yucky_Cursor;
    DEALLOCATE yucky_Cursor;
END;

我怀疑有一种方法可以重构并删除游标并使用基于集合的操作。

答案 1 :(得分:0)

当您插入多条记录时,需要cursor/while为每条记录调用AddConferenceDay程序。

但我建议你改变你的程序以接受表类型作为输入参数。因此,不止一个IDdayC作为AddConferenceDay程序的输入。它比您目前的方法更有效。

类似这样的事情

create type udt_Conferences as table (ID int,dayC int)

更改程序以使用udt_Conferences作为输入参数

Alter procedure AddConferenceDay (@input udt_Conferences readonly)
as 
begin
/* use @input table type instead of @Id and @counter variables */
end

要调用该过程,请使用创建的udt

更新触发器
ALTER TRIGGER [dbo].[ConferenceDayTrigger]
ON [dbo].[Conferences]
AFTER INSERT
AS 
BEGIN
Declare @input udt_Conferences

insert into @input (ID,dayC)
select IDConference,DATEDIFF(DAY, start,finish)  from Inserted
END

答案 2 :(得分:0)

将这些行添加到触发器

插入后 如 BEGIN

const m = str.match(regex);
console.log(m[3]); // 4969694