为什么我的 T-SQL 游标执行了两次?

Why is my T-SQL cursor executing twice?

SQL-服务器代码:

Declare @offers VARCHAR(100)
Declare @offers_seq VARCHAR(100)

Declare Result Cursor
    For Select Top 1 Offers,Offers_seq From [REZJQWB01]..ActiveBooking_OffersDetails_Seq
Open Result
While @@fetch_status=0
Begin
    Fetch Next From Result Into @offers, @offers_seq
    Declare @value VARCHAR(100) = @offers
    While len(@value) >= 1
    Begin
        Set @value = substring(@value,charindex(';',@value)+1,len(@value))
        Print @value
    End
End
Close Result
Deallocate Result

我在这里要完成的是拆分一个单元格中存在的一组分隔值,然后为整个列创建一个游标。我第一次 运行 这段代码给出了以下输出:

2;6;7;8;9;12;13;14;17;19;21;
6;7;8;9;12;13;14;17;19;21;
7;8;9;12;13;14;17;19;21;
8;9;12;13;14;17;19;21;
9;12;13;14;17;19;21;
12;13;14;17;19;21;
13;14;17;19;21;
14;17;19;21;
17;19;21;
19;21;
21;

2;6;7;8;9;12;13;14;17;19;21;
6;7;8;9;12;13;14;17;19;21;
7;8;9;12;13;14;17;19;21;
8;9;12;13;14;17;19;21;
9;12;13;14;17;19;21;
12;13;14;17;19;21;
13;14;17;19;21;
14;17;19;21;
17;19;21;
19;21;
21;

理想情况下它应该只打印一次,但我不确定为什么要循环 运行 两次。我第二次 运行 时,输出为:'Command(s) completed successfully'.

请帮忙。 谢谢

它是 运行 两次的原因是您在 之后才进行提取,您已经检查了 @@fetch_status

步骤如下:

  1. 检查 @@fetch_status,它是零,因为没有获取任何内容。
  2. 获取结果
  3. 运行 你的子字符串代码
  4. 再次检查@@fetch_status,还是0,因为上一步取了一条记录
  5. 获取另一个结果,失败但光标仍指向与之前相同的行
  6. 运行 再次输入你的子字符串代码,结果相同
  7. 再次检查 @@fetch_status,现在 returns -1 因为之前的提取失败。

出于与从 运行 得到两个结果相同的原因,第二次您什么也得不到,因为 @@fetch_status 是上一次执行的 -1。要解决这两个问题,您需要在检查状态之前获取。通常您会看到使用了以下方法之一(伪代码留作练习供您实施)。通常我使用第一个选项,但有些人发现第二个更容易阅读:

-- (declare and open cursor)
while 1=1 begin
    fetch next from cursor
    if @@fetch_status <> 0 break;
    -- (do stuff)
end

-- (declare and open cursor)
fetch next from cursor
while @@fetch_status = 0 begin
    -- (do stuff)
    fetch next from cursor
end

正确代码:

Declare @offers VARCHAR(100)
Declare @offers_seq VARCHAR(100)

Declare Result Cursor
    For Select Top 1 Offers,Offers_seq From [REZJQWB01]..ActiveBooking_OffersDetails_Seq
Open Result
While 1=1
Begin
    Fetch Next From Result Into @offers, @offers_seq
    If @@fetch_status <> 0 Break;
    Declare @value VARCHAR(100) = @offers
    While len(@value) > 1
    Begin
        Set @value = substring(@value,charindex(';',@value,2)+1,len(@value))
        Set @value = ';'+@value
        If len(@value) <= 1 Break;
        Print @value
    End
End
Close Result
Deallocate Result

结果:

;6;7;8;9;12;13;14;17;19;21;
;7;8;9;12;13;14;17;19;21;
;8;9;12;13;14;17;19;21;
;9;12;13;14;17;19;21;
;12;13;14;17;19;21;
;13;14;17;19;21;
;14;17;19;21;
;17;19;21;
;19;21;
;21;