2010-01-29 2 views
1

Il existe une différence entre la façon dont le code suivant s'exécute sur sql2008 et sql2000. en sql 2000 le résultat est correct (le fetch est normal de la première ligne à la dernière ligne) tandis qu'en sql 2008 le fetch montre un comportement étrange (commence à partir de la dernière ligne insérée jusqu'à la première ligne) ci-dessous est le code du problème où 'zone' est une table:sql 2008 différence de curseur avec sql2000?

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 

ci-dessous est le résultat showig dans SQL Server 2008:

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 

et le résultat affiché dans SQL 2000 est:

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 

Répondre

4

Si vous utilisez les sorts ou dans SQL2008, il passe du dernier au premier. Vous avez raison, SQL a changé sa règle de sélection. En général, il est préférable d'utiliser le curseur comme ceci. Utilisez OrderBy.

+0

Y at-il une option que je peux définir pour l'utiliser de la manière normale comme SQL 2000? –

+1

Je connais le moyen d'ajouter "order by" pour votre instruction select. Cela fonctionne pour sql2000 et aussi pour sql2008. – NetSide

1

Vous ne spécifiez pas de clause ORDER BY dans l'instruction select qui vous définit le curseur. Sans ORDER BY, l'ordre des lignes dans un jeu de résultats est non déterministe.

C'est le cas à la fois dans SQL 2000 et 2008 - c'est essentiellement une coïncidence que les commandes de lignes sont comme elles sont.

EDIT

J'ai créé un test sur SQL Server 2008 SP1, y compris la clause ORDER BY ajoutée par l'OP sur la première édition, et ne peut pas reproduire le comportement décrit:

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 

je suis arrivé ce qui suit résultat

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 
+0

ce n'est pas une coïncidence –

+1

C'est plus ou moins une coïncidence. Vous avez utilisé l'algorithme de tri choisi par MS pour ce type d'opérations. Cela n'a jamais été documenté ni garanti pour rester le même pour toujours. Apparemment, MS a changé cet algorithme maintenant. Si vous souhaitez que votre code soit protégé contre tout algorithme de moteur sous-jacent, utilisez la clause ORDER BY. –

+0

@Microgen - Je ne peux pas reproduire le comportement que vous décrivez dans les tests –