为什么我的 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
。
步骤如下:
- 检查
@@fetch_status
,它是零,因为没有获取任何内容。
- 获取结果
- 运行 你的子字符串代码
- 再次检查
@@fetch_status
,还是0,因为上一步取了一条记录
- 获取另一个结果,失败但光标仍指向与之前相同的行
- 运行 再次输入你的子字符串代码,结果相同
- 再次检查
@@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;
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
。
步骤如下:
- 检查
@@fetch_status
,它是零,因为没有获取任何内容。 - 获取结果
- 运行 你的子字符串代码
- 再次检查
@@fetch_status
,还是0,因为上一步取了一条记录 - 获取另一个结果,失败但光标仍指向与之前相同的行
- 运行 再次输入你的子字符串代码,结果相同
- 再次检查
@@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;