遗留应用程序使用而不是触发器对表执行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或其他其他知识库中找不到这个问题的参考。这只是 TRIGGERS EVIL的情况吗?
我可以影响@@ ROWCOUNT吗?
答案 0 :(得分:3)
某些陈述可能会在触发器内改变@@ ROWCOUNT。
声明
SELECT * FROM INSERTED WHERE COL1 < 5
执行并将@@ ROWCOUNT设置为1
发表声明
SET NOCOUNT ON;
然后
IF NOT EXISTS (SELECT * FROM INSERTED WHERE COL1 < 5)
BEGIN
SET NOCOUNT OFF;
INSERT INTO dbo.ACCOUNT_CREDITS (COL1, COL2)
SELECT COL1, COL2 from INSERTED
END
答案 1 :(得分:1)
我需要主流程上下文中的信息,该信息仅在触发器的上下文中可用。
无论是从获取@@ROWCOUNT
还是其他触发器,或者甚至将信息传递给触发器,都有两种方法可以与触发器共享信息:
本地临时表(即名称以单#
开头的表格:#tmp
)
我在DBA.StackExchange:Passing info on who deleted record onto a Delete trigger的相关问题的答案中发布了一个使用CONTEXT_INFO
的示例。关于该问题的评论中有关于CONTEXT_INFO
可能出现的并发症的讨论,所以我使用临时表格发布了another answer该问题。
由于该示例涉及将信息发送到一个触发器,下面是一个从获取信息的示例,因为这就是这个问题:
首先:创建一个简单的表格
CREATE TABLE dbo.InsteadOfTriggerTest (Col1 INT);
第二名:创建触发器
CREATE TRIGGER dbo.tr_InsteadOfTriggerTest
ON dbo.InsteadOfTriggerTest
INSTEAD OF INSERT
AS
BEGIN
PRINT 'Trigger (starting): ' + CONVERT(NVARCHAR(50), @@ROWCOUNT);
SET NOCOUNT ON; -- do AFTER the PRINT else @@ROWCOUNT will be 0
DECLARE @Rows INT;
INSERT INTO dbo.InsteadOfTriggerTest (Col1)
SELECT TOP (5) ins.Col1
FROM inserted ins;
SET @Rows = @@ROWCOUNT;
PRINT 'Trigger (after INSERT): ' + CONVERT(NVARCHAR(50), @Rows);
-- make sure temp table exists; no error if table is missing
IF (OBJECT_ID('tempdb..#TriggerRows') IS NOT NULL)
BEGIN
INSERT INTO #TriggerRows (RowsAffected)
VALUES (@Rows);
END;
END;
第三:进行测试
SET NOCOUNT ON;
IF (OBJECT_ID('tempdb..#TriggerRows') IS NOT NULL)
BEGIN
DROP TABLE #TriggerRows;
END;
CREATE TABLE #TriggerRows (RowsAffected INT);
INSERT INTO dbo.InsteadOfTriggerTest (Col1)
SELECT so.[object_id]
FROM [master].[sys].[objects] so;
PRINT 'Final @@ROWCOUNT (what we do NOT want): ' + CONVERT(NVARCHAR(50), @@ROWCOUNT);
SELECT * FROM #TriggerRows;
输出(在“消息”选项卡中):
触发(开始):91
触发(INSERT后):5
最终@@ ROWCOUNT(我们不想要的):91
结果:
的RowsAffected
5