T-SQL:游标迭代不在@@ FETCH_STATUS = -1处停止

时间:2014-09-27 13:18:37

标签: sql-server tsql while-loop cursor fetch

我在存储过程中创建了一个简单的游标。游标只是迭代表的所有行。

从我的输出看来,迭代器似乎取n + 1行。

我尝试过打破迭代的while循环,但这并没有解决问题。 怎么样?

ALTER PROC spInsertNewCategory --spInsertNewCategory '-1','-1'
@categoryName NVARCHAR(80),
@categoryInfo NVARCHAR(80)
AS 
BEGIN

    DECLARE @siteLanguage_id      INT
    DECLARE @lang_id              INT
    DECLARE @default_siteLanguage INT

    DECLARE cr_siteLanguage       CURSOR
    FOR 
    SELECT sl.siteLanguage_id, sl.lang_id, sl.default_siteLanguage 
    FROM siteLanguage sl


    OPEN cr_siteLanguage
        FETCH NEXT FROM cr_siteLanguage
        INTO @siteLanguage_id,@lang_id,@default_siteLanguage
        PRINT '@siteLanguage_id: '+ CAST(@siteLanguage_id AS NVARCHAR(3))+' fetch: '+ CAST(@@FETCH_STATUS AS NVARCHAR(5))

        WHILE (@@FETCH_STATUS = 0)
            BEGIN
            IF (@@FETCH_STATUS=-1)
                BEGIN
                PRINT 'in if -1'
                BREAK
                END
            FETCH NEXT FROM cr_siteLanguage
            INTO @siteLanguage_id,@lang_id,@default_siteLanguage
            PRINT '@siteLanguage_id: '+ CAST(@siteLanguage_id AS NVARCHAR(3))+' fetch: '+ CAST(@@FETCH_STATUS AS NVARCHAR(5))
            END
    CLOSE cr_siteLanguage
    DEALLOCATE cr_siteLanguage 

    SELECT * FROM siteLanguage
END

enter image description here enter image description here

2 个答案:

答案 0 :(得分:2)

是的,它停在@@ FETCH_STATUS = -1
这就是为什么你没有看到你的PRINT' in -1'
在最后一个FETCH @@ FETCH_STATUS = -1并退出WHILE(@@ FETCH_STATUS = 0)

不,它不能获取n + 1行 在n + 1时,它知道没有更多的行 光标不知道它何时是最后一行 - 它只知道何时没有更多行(n + 1)
这就是你在循环之前获取第一行的原因 在循环内的FETCH之后打印
所以你得到了最后的-1
然后它退出WHILE(@@ FETCH_STATUS = 0)
在调试中运行并观察

OPEN cr_siteLanguage
        FETCH NEXT FROM cr_siteLanguage
        INTO @siteLanguage_id,@lang_id,@default_siteLanguage

        WHILE (@@FETCH_STATUS = 0)
            BEGIN
            PRINT '@siteLanguage_id: '+ CAST(@siteLanguage_id AS NVARCHAR(3))+' fetch: '+ CAST(@@FETCH_STATUS AS NVARCHAR(5))
            IF (@@FETCH_STATUS=-1)
                BEGIN
                PRINT 'in if -1'
                BREAK
                END
            FETCH NEXT FROM cr_siteLanguage
            INTO @siteLanguage_id,@lang_id,@default_siteLanguage               
            END
    CLOSE cr_siteLanguage
    DEALLOCATE cr_siteLanguage 

答案 1 :(得分:0)

@@ FETCH_STATUS = -1 时,似乎永远不会执行IF (@@FETCH_STATUS=-1)
您在进入循环后立即检查 @@ FETCH_STATUS 的值,
具有 WHERE 子句(@@ FETCH_STATUS = 0)

你可以在循环内的FETCH NEXT stmt之后验证。

WHILE (@@FETCH_STATUS = 0)
BEGIN
    FETCH NEXT FROM cr_siteLanguage
    INTO @siteLanguage_id,@lang_id,@default_siteLanguage
    PRINT '@siteLanguage_id: '+ CAST(@siteLanguage_id AS NVARCHAR(3))+' fetch: '+ CAST(@@FETCH_STATUS AS NVARCHAR(5))
    IF (@@FETCH_STATUS=-1)
    BEGIN
        PRINT 'in if -1'
        BREAK
    END
END

注意:我假设第一个FETCH NEXT stmt(紧接在OPEN cr_siteLanguage之后)确实检索记录。