SQL Server - 重写触发器以避免基于游标的方法 [英] SQL Server - Rewrite trigger to avoid cursor based approach

查看:17
本文介绍了SQL Server - 重写触发器以避免基于游标的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我有带有两列 num1num2 的表 Test 以及下面的触发器,它只会在插入 num1 时增加 num2:

If I have table Test with two columns num1 and num2 and the following trigger on it which just increments num2 on inserts of num1:

 DECLARE @PROC_NEWNUM1 VARCHAR (10)
 DECLARE @NEWNUM2 numeric(20)
 DECLARE my_Cursor CURSOR FOR SELECT num1 FROM INSERTED;

 OPEN my_Cursor 
 FETCH NEXT FROM my_Cursor into @PROC_NEWNUM1

 WHILE @@FETCH_STATUS = 0 
 BEGIN 

 select @NEWNUM2 = MAX(num2) from TEST
 if @NEWNUM2 is null
 Begin
    set  @NEWNUM2  = 0
 End
 set @NEWNUM2 = @NEWNUM2 + 1
 UPDATE TEST SET num2 = @NEWNUM2  WHERE num1 = @PROC_NEWNUM1
 FETCH NEXT FROM my_Cursor into @PROC_NEWNUM1  
 END

CLOSE my_Cursor
DEALLOCATE my_Cursor

有没有办法使用基于集合的方法重写上述内容?

(如果有人想知道我为什么这样做,这里是背景:SQL Server 处理多行插入的触发器)

(In case anyone wants to know why I am doing this, here is the background: SQL Server A trigger to work on multiple row inserts)

不使用 Row_Number 的临时表的解决方案(仅限 Sql 2005 以后):

Solution without temp table using Row_Number (Sql 2005 onwards only):

SELECT @MAXNUM2 = MAX(num2) FROM TEST
if @MAXNUM2 IS NULL
BEGIN
    SET @MAXNUM2=0
END

UPDATE TEST
SET num2 = @MAXNUM2 + SubQuery.R
FROM
(
SELECT num1, ROW_NUMBER() OVER (ORDER BY num1) as R FROM inserted
)
SubQuery
INNER JOIN TEST on SubQuery.num1 =  TEST.num1

推荐答案

DECLARE @MAXNUM2 numeric(20)

-- First make an auto increment table starting at 1
DECLARE @tmp table 
( 
   aNum int identity(1,1),
   pInsNum varchar(10)
)

INSERT INTO @tmp (pInsNum)
  SELECT num1 FROM INSERTED;

-- Now find offset
SELECT @MAXNUM2 = MAX(num2) FROM TEST

IF @MAXNUM2 is null
BEGIN
 SET @MAXNUM2  = 0
END

-- Do update
UPDATE TEST
SET num2 = @MAXNUM2 + aNum
FROM TEST 
   INNER JOIN @tmp t ON t.pInsNum = TEST.num1

注意:我无法对此进行测试,可能有错别字.

Note: I was not able to test this, there might be typos.

另外,我确定有一个使用 ROWNUMBER 的非临时表解决方案,但我懒得去查找语法.但是您可以使用它作为获得该答案的指南,而不是使用临时表将 1 到 N 的数字使用 ROWNUMBER 并将其添加到偏移量 (@maxnum2)

Also, I'm sure there is a non-temp table solution using ROWNUMBER, but I am too lazy to go look up the syntax. But you can use this as a guide to get to that answer, instead of using the temp table to make the numbers from 1 to N use ROWNUMBER and add that to the offset (@maxnum2)

这篇关于SQL Server - 重写触发器以避免基于游标的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆