如何在SQL Server触发器中测试多行操作?

时间:2009-01-02 20:25:14

标签: sql-server database

我的幼儿园SQL Server告诉我,在插入和删除的伪表中可能会触发多行触发器。考虑到这一点,我主要编写我的触发器代码,经常导致一些基于游标的cludge。现在我真的只能测试它们一次射击一行。如何生成多行触发器并且SQL Server实际上是否会发送多行触发器?我可以设置一个标志,以便SQL Server只会触发单行触发器吗?

5 个答案:

答案 0 :(得分:9)

触发器定义应始终处理多行。

取自SQLTeam

-- BAD Trigger code following:

CREATE TRIGGER trg_Table1 
ON Table1 
For UPDATE
AS
DECLARE @var1 int, @var2 varchar(50)

SELECT @var1 = Table1_ID, @var2 = Column2
FROM inserted

UPDATE Table2
SET SomeColumn = @var2
WHERE Table1_ID = @var1

上述触发器仅适用于已插入表格中的最后一行。

这是你应该如何实现的:

CREATE TRIGGER trg_Table1 
ON Table1 
FOR UPDATE
AS

UPDATE t2
SET SomeColumn = i.SomeColumn
FROM Table2 t2
INNER JOIN inserted i
ON t2.Table1_ID = i.Table1_ID

答案 1 :(得分:4)

是的,如果语句影响多行,则应由单个触发器调用处理,因为您可能希望还原整个事务。它不可能在逻辑上将它拆分为单独的触发器调用,我不认为SQL Server提供这样的标志。您可以通过发出影响多行的UPDATE或DELETE语句,使SQL Server通过多行调用您的触发器。

答案 2 :(得分:1)

首先,我担心你使用游标使触发器处理多行。不要那样做!使用基于集的语句,而不是jioining到插入或删除的pseudotables。在我来这里工作之前,有人将这些基于游标的触发器之一放在我们的数据库中。处理400,00记录插入花了40多分钟(我经常需要为一个客户端插入超过100,000条记录到此表)。将其更改为基于集合的解决方案会将时间更改为不到一分钟。虽然所有触发器都必须能够处理多行,但您不能通过创建性能噩梦来实现这一目标。

如果你可以为cusor编写一个select语句,你可以根据基于set的相同select语句编写插入,更新或删除。

答案 3 :(得分:0)

我总是写我的触发器来处理多行,我的理解是,如果单个查询插入/更新/删除了多行,那么只有一个触发器会触发,因此你必须使用光标来移动记录一个接一个。

答案 4 :(得分:0)

一个SQL语句总是调用一个触发器执行 - 这是触发器定义的一部分。 (这也是一种情况,似乎至少一次绊倒每个写入触发器的人。)我相信你可以通过检查@@ ROWCOUNT来发现有多少记录受到影响。