有效的SQL Server触发器 - 只触发一次

时间:2010-01-15 14:42:03

标签: sql-server tsql triggers

我希望在更改表数据时进行一些计算。但是,我手动更新我的表并一次复制约3000行。这使我的触发器工作3000次,但我希望它只触发一次。

有办法吗?

感谢。

6 个答案:

答案 0 :(得分:5)

你的发言是什么?

如果您有多个插入,则会针对您正在运行的每个插件触发。如果您希望它只对多个插入执行一次,您必须:

  1. 将您的插入内容写在insert into foo select * from bar
  2. 等单一语句中
  3. 您的触发器不能每行
  4. 其他可能性可能是:

    1. 禁用触发器
    2. 执行您的插入
    3. 将触发器代码放入存储过程
    4. 运行存储过程

答案 1 :(得分:1)

问题是由于您手动粘贴3000行而导致的。你真的有2个解决方案。您可以通过执行以下操作来关闭触发器:

ALTER TABLE tablename DISABLE TRIGGER ALL 
-- do work here 
ALTER TABLE tablename ENABLE TRIGGER ALL

然后在结束时运行触发器的内容,或者可以将3000列放入临时表中,然后一次性插入它们。这只会设置1个触发器。如果这还不够,请向我们提供有关您尝试做什么的更多信息。

答案 2 :(得分:1)

如果通过“手动”表示您正在复制并粘贴到某个用户界面工具(如Access dataGrid)或类似的东西,那么该工具可能每行发出一个插入语句,在这种情况下,您就出局了幸运的是,每个insert语句将执行一次数据库触发器。正如其他答案所提到的,如果您可以使用单个insert语句将行直接插入数据库,那么触发器只会触发一次。

答案 3 :(得分:0)

如果在单个语句中修改3000行,则触发器不会触发3000次。您的触发器将触发一次,虚拟“已删除”表中将有3000行。

答案 4 :(得分:0)

如果限制如何将数据导入到每行执行一次插入的系统中,我建议您将数据导入中间表,然后从中间表插入到最终表中。 / p>

答案 5 :(得分:0)

有更好的方法。

重新链接触发器创建或更改的表,将它们与预期要更改或添加的表进行比较,并通过简单的WHERE子句避免使用触发器。

例如-我使用此触发器来插入一条记录,但仅基于一次存在的列值(@ack)插入一次。

DECLARE @ack INT
SELECT @ack = (SELECT TOP 1 i.CUSTOM_BOOL_1 AS [agent_acknowledged] FROM inserted AS i)
IF @ack = 1
BEGIN
    INSERT INTO TABLEA(
       COLA, COLB, etc
    )
    SELECT
       COLA, COLB, etc
    from inserted as i
        LEFT JOIN TABLEA AS chk --relink to the INSERT table to see if the record already exists
            ON chk.COLA = i.COLA
           AND chk.COLB = i.COLB
           AND etc
    WHERE chk.ID IS NULL  --and here we say if NOT found, then continue to insert
END
相关问题