我已经设置了一个奇怪行为的小例子
SET NOCOUNT ON;
create table #tmp
(id int identity (1,1),
value int);
insert into #tmp (value) values(10);
insert into #tmp (value) values(20);
insert into #tmp (value) values(30);
select * from #tmp;
declare @tmp_id int, @tmp_value int;
declare tmpCursor cursor for
select t.id, t.value from #tmp t
--order by t.id;
open tmpCursor;
fetch next from tmpCursor into @tmp_id, @tmp_value;
while @@FETCH_STATUS = 0
begin
print 'ID: '+cast(@tmp_id as nvarchar(max));
if (@tmp_id = 1 or @tmp_id = 2)
insert into #tmp (value)
values(@tmp_value * 10);
fetch next from tmpCursor into @tmp_id, @tmp_value;
end
close tmpCursor;
deallocate tmpCursor;
select * from #tmp;
drop table #tmp;
我们可以在 print
的帮助下观察游标如何解析 #tmp
表中的新行。但是,如果我们在游标声明中取消注释 order by t.id
- 新行将不会被解析。
这是预期的行为吗?
最佳答案
您看到的行为相当微妙。默认情况下,SQL Server 中的游标是动态的,因此您希望看到更改。然而,埋在documentation是这一行:
SQL Server implicitly converts the cursor to another type if clauses in select_statement conflict with the functionality of the requested cursor type.
当您包含order by
时,SQL Server 会读取所有数据并将其变成一个临时表以供排序。在此过程中,SQL Server 还必须将游标类型从动态更改为静态。这没有特别详细的记录,但您可以很容易地看到这种行为。
关于sql - 为什么为使用 ORDER by 的选择打开的游标不反射(reflect)对后续表的更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14172501/