我正在运行一组基于我提前确定的参数的迭代SQL查询。执行此.sql脚本中的每组查询,并将一行插入临时表。我想要做的是在我将一行插入临时表后停止执行其余的语句。为此,我在每次INSERT后检查@@ ROWCOUNT值。如果它是0,那么我继续下一个INSERT语句。如果是<> 0然后我想停下来。我看到一些有趣的效果,我想知道当我检查它时是否会改变@@ ROWCOUNT。 这是一个基本的例子:
create #temptable
INSERT INTO #temptable (...) SELECT a,b..,n FROM TABLE1 where param1=x1 and param2=x2
IF @@ROWCOUNT = 0
INSERT INTO #temptable (...) SELECT a,b..,n FROM TABLE1 where param1=y1 and param2=x2
IF @@ROWCOUNT = 0
INSERT INTO #temptable (...) SELECT a,b..,n FROM TABLE1 where param1=z1 and param2=x2
IF @@ROWCOUNT = 0
INSERT INTO #temptable (...) SELECT a,b..,n FROM TABLE1 where param1=x1 and param2=y2
IF @@ROWCOUNT = 0
INSERT INTO #temptable (...) SELECT a,b..,n FROM TABLE1 where param1=y1 and param2=y2
IF @@ROWCOUNT = 0
INSERT INTO #temptable (...) SELECT a,b..,n FROM TABLE1 where param1=z1 and param2=y2
我所看到的是,当第一个INSERT有行时,它不执行第二个INSERT,但 执行第三个INSERT。然后它不会执行第4次INSERT,但它会执行第5次等等。不应该停止所有进一步执行或是否有一些范围正在被更改?
一旦INSERT语句将一行插入临时表,有没有办法让这个SQL停止?
答案 0 :(得分:4)
@@ROWCOUNT
会被执行的每个语句重置,并且包含IF语句;这就是为什么你通常做的第一件事,当你关心它时,将它捕获到一个变量中,以便你可以在事后用值来做事而不用担心它已经改变了。
UPDATE(无耻的自我推销,真的):如果你想看到你的SQL自动拆分成语句(所以你会看到每个IF / INSERT组合构成一个语句),你可以通过SQL Formatter传递它就像我的PoorSQL.com网站一样 - 它会在语句之间放一个空行! :)
另外:很好地快速概述了如何处理这个问题,这也适用于@@ERROR
:http://www.novicksoftware.com/TipsAndTricks/sql-error-reset-after-every-statement.htm(尽管在SQL 2005及更高版本中你应该使用try / catch而不是{{ 1}})
答案 1 :(得分:3)
只需创建一个变量来保存ROWCOUNT,然后就可以做你想要的了 e.g。
DECLARE @RCount int
INSERT INTO #temptable (...) SELECT a,b..,n FROM TABLE1 where param1=x1 and param2=x2
SET @RCount = @@ROWCOUNT
IF @RCount = 0
BEGIN
INSERT INTO #temptable (...) SELECT a,b..,n FROM TABLE1 where param1=y1 and param2=x2
SET @RCount = @@ROWCOUNT
END
IF @RCount = 0
BEGIN
INSERT INTO #temptable (...) SELECT a,b..,n FROM TABLE1 where param1=z1 and param2=x2
SET @RCount = @@ROWCOUNTE
END
....
在这种情况下可用的另一个选项是向插入内容添加Where
条件
INSERT INTO #temptable (...) SELECT a,b..,n FROM TABLE1 where param1=x1 and param2=x2
INSERT INTO #temptable (...) SELECT a,b..,n FROM TABLE1 where param1=y1 and param2=x2
WHERE NOT EXISTS (SELECT * FROM temptable )
INSERT INTO #temptable (...) SELECT a,b..,n FROM TABLE1 where param1=y1 and param2=x2
WHERE NOT EXISTS (SELECT * FROM temptable )
INSERT INTO #temptable (...) SELECT a,b..,n FROM TABLE1 where param1=y1 and param2=x2
WHERE NOT EXISTS (SELECT * FROM temptable )
答案 2 :(得分:3)
因为@@ rowcount只能检查一次,所以你的脚本会跳过一次插入,然后执行下一次插入。您必须正确嵌套IF:
创建#temptable
INSERT INTO #temptable (...) SELECT a,b..,n FROM TABLE1 where param1=x1 and param2=x2
IF @@ROWCOUNT = 0
begin
INSERT INTO #temptable (...) SELECT a,b..,n FROM TABLE1 where param1=y1 and param2=x2
IF @@ROWCOUNT = 0
begin
INSERT INTO #temptable (...) SELECT a,b..,n FROM TABLE1 where param1=z1 and param2=x2
IF @@ROWCOUNT = 0
begin
INSERT INTO #temptable (...) SELECT a,b..,n FROM TABLE1 where param1=x1 and param2=y2
IF @@ROWCOUNT = 0
begin
INSERT INTO #temptable (...) SELECT a,b..,n FROM TABLE1 where param1=y1 and param2=y2
IF @@ROWCOUNT = 0
INSERT INTO #temptable (...) SELECT a,b..,n FROM TABLE1 where param1=z1 and param2=y2
end
end
end
end
通过在相反条件下使用循环和中断(<>0
),有一些方法可以使这更优雅(避免深刻的嵌套):
create #temptable
while (1=1)
begin
INSERT INTO #temptable (...) SELECT a,b..,n FROM TABLE1 where param1=x1 and param2=x2
IF @@ROWCOUNT <> 0
break
INSERT INTO #temptable (...) SELECT a,b..,n FROM TABLE1 where param1=y1 and param2=x2
IF @@ROWCOUNT <> 0
break
INSERT INTO #temptable (...) SELECT a,b..,n FROM TABLE1 where param1=z1 and param2=x2
IF @@ROWCOUNT <> 0
break
INSERT INTO #temptable (...) SELECT a,b..,n FROM TABLE1 where param1=x1 and param2=y2
IF @@ROWCOUNT <> 0
break
INSERT INTO #temptable (...) SELECT a,b..,n FROM TABLE1 where param1=y1 and param2=y2
IF @@ROWCOUNT <> 0
break
INSERT INTO #temptable (...) SELECT a,b..,n FROM TABLE1 where param1=z1 and param2=y2
break
end
答案 3 :(得分:0)
我最近发生了这种情况,这是由“美容原因”引起的。
INSERT INTO asd
VALUES a, s, d
IF @@rowcount > 0
...
……还有……
INSERT INTO asd
VALUES a, s, d
IF @@rowcount > 0
...
不被视为彼此相等。由于某种原因,行之间的额外空间(看起来更好)会重置 @@rowcount。