【发布时间】:2011-05-16 09:44:18
【问题描述】:
旧版应用使用代替触发器对表执行 INSERT,然后使用行数进行进一步处理。
我们现在需要使用INSTEAD OF INSERT 触发器来选择退出某些 INSERT。
问题是@@ROWCOUNT 仍然返回尝试插入的数量。
例如,一个永远不会完成插入的虚构触发器可能是
ALTER TRIGGER [dbo].[trig_ACCOUNT_CREDITS_RunningTotalINSERT]
ON [dbo].[ACCOUNT_CREDITS]
INSTEAD OF INSERT
AS
BEGIN
--tried with NOCOUNT ON and OFF
SET NOCOUNT OFF;
--This is an example of the branching logic that might determine
--whether or not to do the INSERT
IF 1=2 --no insert will ever occur (example only)
BEGIN
INSERT INTO dbo.ACCOUNT_CREDITS (COL1, COL2)
SELECT COL1, COL2 from INSERTED
END
END
有些 INSERT 语句可能是
--No rows will be inserted because value of COL1 < 5
INSERT INTO dbo.ACCOUNT_CREDITS (COL1, COL2) VALUES ( 3, 3)
--We would assume row count to be 0, but returns 1
select @@ROWCOUNT
--No rows will be inserted because value of COL1 < 5
INSERT INTO dbo.ACCOUNT_CREDITS (COL1, COL2)
SELECT 1, 1
union all
SELECT 2, 2
--We would assume row count to be 0, but returns 2
select @@ROWCOUNT
我可以解决这个问题,但我无法信任 @@ROWCOUNT 让我很困扰。我在 SO 或那些 other 知识库中找不到有关此问题的参考。这仅仅是 TRIGGERS ARE EVIL 的一个例子吗?
我可以影响@@ROWCOUNT 吗?
【问题讨论】:
-
我的意思是决定是否实际进行 INSERT。根据 INSERTED TABLE 的值,可能不会发生 INSERT。我会更新我的问题,以便更清楚。
-
当你有一个 INSTEAD OF 触发器,你试图通过使用另一个 INSTEAD OF 触发器来覆盖它的动作时,我的直觉反应是你在触发器中有太多的逻辑,你可能已经被数据库的黑暗面吸引。那就是疯狂。回头,回头,在为时已晚之前!啊啊啊啊!邪神!!! (别问我是怎么知道的……)
-
@Bob。我喜欢“放弃所有希望”的情绪,并能清晰地听到你的声音。在这种情况下,我正在查看的是单个触发器,它可能会也可能不会根据“东西”进行插入。仍然很邪恶,但为什么我无法获得准确的行数?
-
听起来像是阻抗不匹配。换句话说,您对数据库服务器的期望和期望与服务器实际所做的并不完全匹配。正如您所指出的,@@ROWCOUNT 正在计算尝试次数(我猜这是您的代码实际发出的 INSERT 次数),而不是在触发器执行期间发生的成功次数。如果可能的话,您最好进行一些重构以删除触发器。触发器并不邪恶,但它们可以在你最不期望的时间和地点咬你。以我的经验,“那个触发器是最好的,它做的最少”。
标签: sql sql-server sql-server-2008 triggers