Simptomi
Kada koristite funkcije SCOPE_IDENTITY()ili @@IDENTITYza dohvaćanje vrijednosti umetnutih u stupac identiteta, možda ćete primijetiti da te funkcije ponekad vraćaju netočne vrijednosti. Problem se pojavljuje samo kada upiti koriste paralelne planove izvršavanja. Dodatne informacije o određivanju hoće li upiti koristiti paralelne planove izvršavanja odnose se na odjeljak Paralelni intra-upit u sljedećem tehničkom članku o Microsoftovim preuzimanjima:
Uzrok
Microsoft je potvrdio da je to problem u Microsoftovim proizvodima koji su navedeni na početku ovog članka.
Rješenje
Informacije o kumulativnom ažuriranju
SQL Server 2008 R2 Service Pack 1
Popravak tog problema prvi je put objavljen u kumulativnom ažuriranju 5 za SQL Server 2008 R2 Service Pack 1. Dodatne informacije o nabavi paketa kumulativnog ažuriranja potražite u članku iz Microsoftove baze znanja pod brojem
2659694Kumulativno ažuriranje paketa 5 za SQL Server 2008 R2 Service Pack 1
NapomenaBudući da su međuverzije kumulativne, svako novo izdanje popravka sadrži sve hitne popravke i sve sigurnosne popravke obuhvaćene prethodnim izdanjem za popravak sustava SQL Server 2008 R2. Preporučujemo da razmislite o primjeni najnovijeg izdanja za popravak koje sadrži taj hitni popravak. Za više informacija kliknite sljedeći broj članka da biste prikazali članak u Microsoftovoj bazi znanja:
2567616Međuverzije sustava SQL Server 2008 R2 objavljene nakon što je objavljen SQL Server 2008 R2 Service Pack 1
Zaobilazno rješenje
Microsoft preporučuje da u upitima ne koristite nijednu od tih funkcija kada su paralelne tarife uključene jer nisu uvijek pouzdane. Umjesto toga upotrijebite uvjet OUTPUT iz izjave INSERT da biste dohvaćali vrijednost identiteta kao što je prikazano u primjeru u nastavku.
Primjer korištenja uvjeta OUTPUT:
DECLARE @MyNewIdentityValues table(myidvalues int)
declare @A table (ID int primary key)
umetanje u @A vrijednosti (1)
deklarirati @B (ID int primary key identity(1;1), B int not null)
umetanje u @B vrijednosti (1)
odaberite
[RowCount] = @@RowCount,
[@@IDENTITY] = @@IDENTITY,
[SCOPE_IDENTITY] = SCOPE_IDENTITY()
postavljanje profila statistike na
umetanje u _ddr_T
izlazni inserted.ID u @MyNewIdentityValues
odaberite
b.ID
iz @A a
left join @B b on b.ID = 1
lijevi spoj @B b2 na b2. B = -1
left join _ddr_T t on t.T = -1
gdje ne postoji (odaberite * iz _ddr_T t2 gdje t2.ID = -1)
postavljanje profila statistike isključeno
odaberite
[RowCount] = @@RowCount,
[@@IDENTITY] = @@IDENTITY,
[SCOPE_IDENTITY] = SCOPE_IDENTITY(),
[IDENT_CURRENT] = IDENT_CURRENT('_ddr_T')
odaberite * iz @MyNewIdentityValues
idi
Ako je za vašu situaciju potrebno koristiti bilo koju od tih funkcija, problem možete zaobilazno riješiti pomoću jednog od sljedećih načina.
Prvi način:
U upit uvrsti sljedeću mogućnost
OPTION (MAXDOP 1)
Napomena:to može nauditi performansama dijela upita SELECT.
Drugi način:
Pročitajte vrijednost iz dijela SELECT u skup varijabli (ili jednu varijablu tablice), a zatim umetnite u ciljnu tablicu pomoću mogućnosti MAXDOP=1. Budući da plan INSERT neće biti paralelno, dobiti ćete pravu semantiku, no odabir će biti paralelno da bi se postigle željene performanse.
Metoda 3:
Pokrenite sljedeću naredbu da biste mogućnost maksimuma paralelnosti postavili na 1:
sp_configure "max degree of parallelism", 1
idi
ponovno konfigurirajte pomoću nadjačavanja
idi
Napomena:ova metoda može uzrokovati degradaciju performansi na poslužitelju. Tu metodu ne biste trebali koristiti osim ako ga niste procijenili u testiranju ili pripremnom okruženju.