Simptome
Atunci când utilizați funcții SCOPE_IDENTITY() sau @@IDENTITYpentru a regăsi valorile inserate într-o coloană de identitate, este posibil să observați că aceste funcții returnează uneori valori incorecte. Problema apare doar atunci când interogările utilizează planuri de executare în paralel. Pentru mai multe informații despre cum să determinați dacă interogările dvs. vor utiliza planuri de executare în paralel, consultați secțiunea Paralelism interogare intra din următorul articol tehnic despre descărcările Microsoft:
Cauză
Microsoft a confirmat că aceasta este o problemă în produsele Microsoft care sunt listate la începutul acestui articol.
Rezolvare
Informații despre actualizarea cumulativă
SQL Server 2008 R2 cu pachetul Service Pack 1
Remedierea pentru această problemă a fost lansată pentru prima dată în Actualizarea cumulativă 5 pentru SQL Server 2008 R2 cu Service Pack 1. Pentru mai multe informații despre obținerea acestui pachet de actualizare cumulativă, faceți clic pe următorul număr de articol pentru a vizualiza articolul din Baza de cunoștințe Microsoft:
2659694Pachetul de actualizare cumulativă 5 pentru SQL Server 2008 R2 Service Pack 1
Notă Deoarece compilări sunt cumulative, fiecare remediere nouă lansată conține toate remedierile rapide și toate remedierile de securitate care au fost incluse în versiunea anterioară de remediere SQL Server 2008 R2. Vă recomandăm să luați în considerare aplicarea celor mai recente lansări de remedieri care conține această remediere rapidă. Pentru mai multe informații, faceți clic pe următorul număr de articol pentru a-l vedea în Baza de cunoștințe Microsoft:
2567616A fost lansată compilări SQL Server 2008 R2 care au fost lansate după ce a fost lansat SQL Server 2008 R2 Service Pack 1
Soluție de evitare
Microsoft recomandă să nu utilizați niciuna dintre aceste funcții în interogările dvs. atunci când planurile paralele sunt implicate, deoarece nu sunt întotdeauna de încredere. În schimb, utilizați clauza OUTPUT a declarației INSERT pentru a regăsi valoarea identității, așa cum se arată în exemplul de mai jos.
Exemplu de utilizare a clauzei OUTPUT:
DECLARE @MyNewIdentityValues tabel(myidvalues int)
declare @A tabel (ID cheie primară int)
insert into @A values (1)
declare @B tabel (ID int primary key identity(1,1), B int not null)
insert into @B values (1)
selectați
[NumărRâruri] = @@RowCount,
[@@IDENTITY] = @@IDENTITY,
[SCOPE_IDENTITY] = SCOPE_IDENTITY()
set statistics profile on
inserare în _ddr_T
output inserted.ID into @MyNewIdentityValues
selectați
b.ID
din @A a
left join @B b on b.ID = 1
left join @B b2 on b2. B = -1
left join _ddr_T t on t.T = -1
unde nu există (selectați * din _ddr_T t2 unde t2.ID = -1)
set statistics profile off
selectați
[NumărRâruri] = @@RowCount,
[@@IDENTITY] = @@IDENTITY,
[SCOPE_IDENTITY] = SCOPE_IDENTITY(),
[IDENT_CURRENT] = IDENT_CURRENT('_ddr_T')
selectați * din @MyNewIdentityValues
accesați
Dacă în situația dvs. este necesar să utilizați oricare dintre aceste funcții, puteți utiliza una dintre metodele următoare pentru a o soluție la problemă.
Metoda 1:
Includeți următoarea opțiune în interogare
OPȚIUNE (MAXDOP 1)
Notă:Acest lucru poate strica performanța părții SELECT a interogării.
Metoda 2:
Citiți valoarea din partea SELECT într-un set de variabile (sau o variabilă cu un singur tabel), apoi inserați în tabelul țintă cu MAXDOP=1. Deoarece planul INSERT nu va fi paralel, veți obține semantica corectă, însă select va fi paralel pentru a obține performanța dorită.
Metoda 3:
Rulați următoarea insistție pentru a seta opțiunea pentru gradul maxim de paralelism la 1:
sp_configure "grad max de paralelism", 1
accesați
reconfigurare cu înlocuire
accesați
Notă:Această metodă poate determina degradarea performanței pe server. Nu trebuie să utilizați această metodă decât dacă ați evaluat-o într-un mediu de testare sau testare.