Simptomi
Izmantojot funkciju SCOPE_IDENTITY()vai @@IDENTITY,lai izgūtu identitātes kolonnā ievietotās vērtības, iespējams, ievērosit, ka šīs funkcijas dažreiz atgriež nepareizas vērtības. Problēma rodas tikai tad, ja vaicājumi izmanto paralēlus izpildes plānus. Lai iegūtu papildinformāciju par to, kā noteikt, vai jūsu vaicājumi izmanto paralēlus izpildes plānus, skatiet intra-query parallelism sadaļu šajā tehniskajā rakstā par Microsoft lejupielādēm:
Cēlonis
Microsoft ir apstiprinājusi, ka šī ir problēma Microsoft produktos, kas norādīti šī raksta sākumā.
Risinājums
Informācija par kumulatīvo atjauninājumu
SQL Server 2008 R2 1. servisa pakotne
Šīs problēmas labojums pirmo reizi tika izlaists 5. kumulatīvajā atjauninājumā SQL Server 2008 R2 1. servisa pakotnei. Lai iegūtu papildinformāciju par to, kā iegūt šo kumulatīvā atjauninājuma pakotni, noklikšķiniet uz šī raksta numura, lai skatītu rakstu Microsoft zināšanu bāzē:
26596945. kumulatīvā atjauninājuma pakotne sql Server 2008 R2 1. servisa pakotnei
Piezīme.Tā kā būvējumu ir kumulatīvi, katrā jaunajā labojuma laidienā ir visi labojumfaili un visi drošības labojumi, kas iekļauti iepriekšējā SQL Server 2008 R2 labojuma laidienā. Ieteicams lietot visjaunāko labojumu laidienu, kurā ir iekļauts šis labojumfails. Lai iegūtu papildinformāciju, noklikšķiniet uz šī raksta numura un skatiet rakstu Microsoft zināšanu bāzē:
2567616SQL Server 2008 R2 būvējumus, kas tika izlaisti pēc SQL Server 2008 R2 1. servisa pakotnes izlaidšanas
Risinājums
Microsoft iesaka izmantot kādu no šīm funkcijām vaicājumos, ja paralēlās plānu funkcijas ir iesaistītas, jo tie ne vienmēr ir uzticami. Tā vietā izmantojiet priekšraksta INSERT klauzulu OUTPUT, lai izgūtu identitātes vērtību, kā parādīts tālāk redzamajā piemērā.
Klauzulas OUTPUT izmantošanas piemērs:
DECLARE @MyNewIdentityValues table(myidvalues int)
declare @A table (ID int primary key)
ievietot @A (1)
declare @B table (ID int primary key identity(1,1), B int not null)
ievietot @B (1)
atlasiet
[RowCount] = @@RowCount,
[@@IDENTITY] = @@IDENTITY,
[SCOPE_IDENTITY] = SCOPE_IDENTITY()
iestatīt statistikas profilu vietnē
ievietošana _ddr_T
izvade inserted.ID ar @MyNewIdentityValues
atlasiet
b.ID
no @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
kur tās nepastāv (atlasiet * no _ddr_T t2, t2.ID = -1)
set statistics profile off
atlasiet
[RowCount] = @@RowCount,
[@@IDENTITY] = @@IDENTITY,
[SCOPE_IDENTITY] = SCOPE_IDENTITY(),
[IDENT_CURRENT] = IDENT_CURRENT('_ddr_T')
atlasiet * no @MyNewIdentityValues
doties
Ja nepieciešams izmantot kādu no šīm funkcijām, varat izmantot kādu no tālāk minētajām metodēm, lai novērstu šo problēmu.
1. metode.
Iekļaujiet vaicājumā tālāk norādīto opciju
OPTION (MAXDOP 1)
Piezīme.Tas var kaitēt vaicājuma daļas SELECT veiktspējai.
2. metode.
Lasīt daļu SELECT vērtību mainīgo kopā (vai vienā tabulas mainīgajā) un pēc tam ievietot mērķa tabulā ar MAXDOP=1. Tā kā inserta plāns nebūs paralēls, iegūstat pareizo semantiku, bet SELECT būs paralēls vēlamās veiktspējas sasniegšanai.
3. metode.
Palaidiet šo priekšrakstu, lai kā paralalisma maksimālās pakāpes opciju iestatītu 1:
sp_configure 'max degree of parallelism', 1
doties
pārkonfigurēšana ar ignorēšanu
doties
Piezīme.Šī metode serverī var izraisīt veiktspējas degradāciju. Šo metodi nedrīkst izmantot, ja vien neesat to novērtējusi testēšanas vai sagatavošanas vidē.