2010-11-15 12 views
3

Si j'ai un déclencheur AFTER UPDATE, seraLes tables 'insérées' et 'effacées' sont-elles garanties de renvoyer leurs enregistrements dans le même ordre dans un déclencheur AFTER UPDATE?

SELECT * FROM inserted 

et

SELECT * FROM deleted 

me rendre leurs dossiers dans le même ordre?

I.e. disons que j'étais capable d'indexer dans leurs ensembles de résultats, va del [5] et ins [5] me rendre les entrées correspondantes, même si une valeur de la clé primaire composée a changé (ce qui serait la raison pour laquelle un intérieur rejoindre ne fonctionnera pas).

Répondre

4

Je ne crois pas qu'il y ait aucune garantie sur l'ordre des rangées à l'intérieur inséré et supprimé - tout comme il n'y a aucune garantie de commande pour la sélection de n'importe quelle table, sans spécifier un ORDER BY. J'ai décidé de voir si je pouvais produire un script où nous pourrions démontrer le manque de commande. Sur ma machine (SQL 2008 Dev), je peux répéter le script suivant. Il sort 2 lignes de inséré et supprimé. Notez que nous ne touchons pas la colonne ID, et donc si la supposition était correcte (qu'ils ont été commandés d'une certaine manière), alors les mêmes ID devraient apparaître dans le même ordre. Ce n'est pas le cas ici.

En premier lieu, les sorties:

ID   D1      V1 
----------- ----------------------- ---------------------------------------------------------------------------------------------------- 
32   2010-03-01 00:00:00.000 text 
60   2010-02-01 00:00:00.000 text 

(2 row(s) affected) 

ID   D1      V1 
----------- ----------------------- ---------------------------------------------------------------------------------------------------- 
60   2010-03-01 00:00:00.000 text 
32   2010-02-01 00:00:00.000 text 

(2 row(s) affected) 

et le script qui a produit ceci:

create table T1 (
    ID int not null, 
    D1 datetime not null, 
    V1 varchar(100) not null, 
    constraint PK_T1 PRIMARY KEY (D1,ID) 
) 
go 
create index IX_T1_D1 on T1(D1) 
go 
insert into T1(ID,D1,V1) 
select ID,DATEADD(day,ID-1,'20100101'),'text' 
from (select ROW_NUMBER() OVER (ORDER BY so1.id) from sysobjects so1,sysobjects so2,sysobjects) t(ID) 
go 
create trigger T_T1_U on T1 after update 
as 
begin 
    select * from inserted 
    select * from deleted 
end 
go 
sp_configure 'disallow results from triggers',0 
go 
RECONFIGURE 
go 
update T1 set D1 = DATEADD(month,CASE WHEN DATEPART(month,D1)=2 THEN 1 ELSE -1 END,D1) 
where D1 in ('20100201','20100301') 
go 
sp_configure 'disallow results from triggers',1 
go 
RECONFIGURE 
go 
drop table T1 
go 
+0

Je craignais autant, c'est pourquoi je demandais. Cela craint, comme ordre par ne m'aidera pas si la clé primaire a changé. –

+0

Vous ne devriez pas avoir de clés primaires qui changent. S'ils le font, ils ne devraient pas être le PK. Il est préférable d'utiliser un substitut dans ces conditions et de placer un index unique sur la clé précédente. – HLGEM

+1

@HLGEM - Je ne recommanderais pas d'avoir à changer de PK (bien que les mises à jour en cascade aident beaucoup, si vous allez le faire). C'était plus un genre de contrat "Puis-je produire un exemple qui est définitivement cassé". –

-2

Si vous avez un PRIMARY KEY sur la table (vous voulez généralement un champ id), ils seront toujours retournés dans le même ordre.

+0

De plus, il n'y a pas de clé sur les tables insérées et supprimées, même si leur table de base a une clé, de sorte que la théorie ne tient même pas pour ces tables. –

+1

Ceci est manifestement faux. Avoir un PK n'est pas une garantie de commande à tout moment. – HLGEM