@@ ROWCOUNT不像我想的那样工作?

时间:2011-07-27 15:18:51

标签: sql-server

我正在运行一组基于我提前确定的参数的迭代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停止?

4 个答案:

答案 0 :(得分:4)

@@ROWCOUNT会被执行的每个语句重置,并且包含IF语句;这就是为什么你通常做的第一件事,当你关心它时,将它捕获到一个变量中,以便你可以在事后用值来做事而不用担心它已经改变了。

UPDATE(无耻的自我推销,真的):如果你想看到你的SQL自动拆分成语句(所以你会看到每个IF / INSERT组合构成一个语句),你可以通过SQL Formatter传递它就像我的PoorSQL.com网站一样 - 它会在语句之间放一个空行! :)

另外:很好地快速概述了如何处理这个问题,这也适用于@@ERRORhttp://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。