以下代码在sql2008和sql2000上的运行方式有所不同。在sql 2000中,结果是正确的(从第一行到最后一行的提取是正常的),而在sql 2008中,提取显示奇怪的行为(从最后插入的行开始直到第一行。下面是问题的代码其中'area'是任何表:
create trigger tr on area for insert as
declare @id int
select @id = id from inserted
print 'trigger: ' + convert(varchar(50), @id)
declare c cursor scroll for select id from inserted order by id
open c
fetch next from c into @id
while @@FETCH_STATUS = 0
begin
print 'cursor id: ' + convert(varchar(50), @id)
fetch next from c into @id
end
close c
deallocate c
下面是sql 2008中的结果showig:
trigger: 1828
cursor id: 1837
cursor id: 1836
cursor id: 1835
cursor id: 1834
cursor id: 1833
cursor id: 1832
cursor id: 1831
cursor id: 1830
cursor id: 1829
cursor id: 1828
,sql 2000中显示的结果是:
trigger: 1837
cursor id: 1828
cursor id: 1829
cursor id: 1830
cursor id: 1831
cursor id: 1832
cursor id: 1833
cursor id: 1834
cursor id: 1835
cursor id: 1836
cursor id: 1837
答案 0 :(得分:4)
如果在SQL 2008中使用游标,它将从最后一个到第一个。你是对的,SQL改变了它的选择规则。一般来说,最好像这样使用游标。使用OrderBy。
答案 1 :(得分:1)
您没有在定义游标的select语句中指定ORDER BY
子句。如果没有ORDER BY
,结果集中的行顺序是不确定的。
在SQL 2000和2008中都是这种情况 - 行顺序就是它们的基本巧合。
修改强>
我在SQL 2008 SP1上创建了一个测试,包括OP在第一次编辑时添加的ORDER BY
子句,并且无法复制所描述的行为:
create table area
(id int)
GO
create trigger tr on area for insert as
declare @id int
select @id = id from inserted
print 'trigger: ' + convert(varchar(50), @id)
declare c cursor scroll for select id from inserted order by id
open c
fetch next from c into @id
while @@FETCH_STATUS = 0
begin
print 'cursor id: ' + convert(varchar(50), @id)
fetch next from c into @id
end
close c
deallocate c
GO
insert area
select 10
union select 9
union select 8
union select 7
union select 6
union select 5
union select 4
union select 3
union select 2
union select 1
我得到了以下结果
trigger: 1
cursor id: 1
cursor id: 2
cursor id: 3
cursor id: 4
cursor id: 5
cursor id: 6
cursor id: 7
cursor id: 8
cursor id: 9
cursor id: 10