T-SQL游标永远不会结束

时间:2013-05-03 10:14:35

标签: sql-server tsql

我已经在谷歌搜索过,但我没有找到问题的答案。在互联网上,一切都说我做得对。 我的问题是 - 我现在正在尝试写下我保存到光标的值(是的,只有那个)。但是我使用它的循环是无穷大,并且它从一开始就一次又一次地从一开始就从光标写入所有值......

CREATE PROCEDURE CreateOrEditClient(...Parameters...) AS
DECLARE c CURSOR FOR SELECT column FROM table;
DECLARE @wrt VARCHAR(20);
DECLARE @tmp INT = 0;
 BEGIN
  OPEN c;
   FETCH NEXT FROM c INTO @wrt;
    WHILE @@FETCH_STATUS = 0
     BEGIN
      print CAST(@tmp AS VARCHAR(10)) + '  ' + @wrt;
      SET @tmp = @tmp +1;
      FETCH NEXT FROM c INTO @wrt;
     END;
  CLOSE c;
  DEALLOCATE c;
END;

EXEC CreateOrEditClient ...;

在我看来,光标写得正确,但输出是:

0  790710/1112
1  900519/5555
2  790716/7877
....
19 111111/1111
0  790710/1112
1  900519/5555
....

并最终写入错误消息“超出最大存储过程,函数,触发器或视图嵌套级别(限制32)。”

如果我只使用

SELECT column FROM table;

它只写了20条记录。

我知道这个例子有更好的解决方案,但我需要知道为什么Cursor不起作用。它将来可能会有用。感谢每一个asnwer。

4 个答案:

答案 0 :(得分:1)

好的,有问题的评论是解决方案。

“EXEC ProcedureName ...;”编译时,不能像过程的主体那样在同一个文件中。

CREATE PROCEDURE CreateOrEditClient(...Parameters...) AS
DECLARE c CURSOR FOR SELECT column FROM table;
DECLARE @wrt VARCHAR(20);
DECLARE @tmp INT = 0;
 BEGIN
  OPEN c;
   FETCH NEXT FROM c INTO @wrt;
    WHILE @@FETCH_STATUS = 0
 BEGIN
  print CAST(@tmp AS VARCHAR(10)) + '  ' + @wrt;
    SET @tmp = @tmp +1;
    FETCH NEXT FROM c INTO @wrt;
 END;
  CLOSE c;
  DEALLOCATE c;
END;

有问题的例子将以递归方式调用过程。 谢谢大家。

答案 1 :(得分:0)

您可能会注意到是否要正确缩进代码。你有:

CREATE PROCEDURE CreateOrEditClient(...Parameters...) AS
DECLARE c CURSOR FOR SELECT column FROM table;
DECLARE @wrt VARCHAR(20);
DECLARE @tmp INT = 0;
BEGIN
    OPEN c;
        FETCH NEXT FROM c INTO @wrt;
        WHILE @@FETCH_STATUS = 0
        BEGIN
            print CAST(@tmp AS VARCHAR(10)) + '  ' + @wrt;
            SET @tmp = @tmp +1;
            FETCH NEXT FROM c INTO @wrt;
        END;
    CLOSE c;
    DEALLOCATE c;
END;

你应该:

CREATE PROCEDURE CreateOrEditClient(...Parameters...) AS
BEGIN
    DECLARE @wrt VARCHAR(20);
    DECLARE @tmp INT = 0;
    DECLARE c CURSOR FOR SELECT column FROM table;
    OPEN c;
        FETCH NEXT FROM c INTO @wrt;
        WHILE @@FETCH_STATUS = 0
        BEGIN
            print CAST(@tmp AS VARCHAR(10)) + '  ' + @wrt;
            SET @tmp = @tmp +1;
            FETCH NEXT FROM c INTO @wrt;
        END;
    CLOSE c;
    DEALLOCATE c;
END;

EXEC CreateOrEditClient ...;

顺便说一句。你的代码甚至运行了吗?对我来说似乎是语法错误。

编辑:哦,参数未在括号AFAIK中声明。例如:

CREATE PROCEDURE tmp_mol_cleanup_db
    @param1 type,
    @param2 type
AS
BEGIN
    -- procedure body
END;

答案 2 :(得分:0)

请试试这个......

BEGIN
    SET NOCOUNT ON ;
    DECLARE @wrt VARCHAR(20)
    DECLARE @tmp INT = 0

    DECLARE Cur_Common CURSOR  FAST_FORWARD READ_ONLY FOR   
    SELECT iID FROM 'YourTable'
    OPEN Cur_Common
    FETCH NEXT FROM Cur_Common INTO @wrt

    WHILE @@FETCH_STATUS = 0 
        BEGIN
            print CAST(@tmp AS VARCHAR(10)) + '  ' + @wrt;
SET @tmp = @tmp +1;

       FETCH NEXT FROM Cur_Common INTO @wrt
        END
        CLOSE Cur_Common
    DEALLOCATE Cur_Common
END

答案 3 :(得分:0)

使用

 DECLARE @tmp INT
 SET @tmp=0
而不是 DECLARE @tmp INT = 0

相关问题