Príznaky
Pri použití funkcie SCOPE_IDENTITY()alebo @@IDENTITYna načítanie hodnôt vložených do stĺpca identity si môžete všimnúť, že tieto funkcie niekedy vrátia nesprávne hodnoty. Problém sa vyskytuje iba v prípade, že dotazy používajú plány paralelného vykonávania. Ďalšie informácie o tom, ako určiť, či vaše dotazy budú používať paralelné plány vykonávania, nájdete v časti Paralelný presun medzi dotazmi v nasledujúcom technickej časti o súboroch na stiahnutie od spoločnosti Microsoft:
Príčina
Spoločnosť Microsoft potvrdila, že ide o problém v produktoch spoločnosti Microsoft, ktoré sú uvedené na začiatku tohto článku.
Riešenie
Informácie o kumulatívnej aktualizácii
SQL Server 2008 R2 Service Pack 1
Oprava tohto problému bola prvýkrát vydaná v kumulatívnej aktualizácii 5 pre SQL Server 2008 R2 Service Pack 1. Ďalšie informácie o tom, ako získať tento balík kumulatívnej aktualizácie, zobrazíte kliknutím na číslo článku vedomostnej databázy Microsoft Knowledge Base:
2659694Balík kumulatívnej aktualizácie 5 pre SQL Server 2008 R2 Service Pack 1
Poznámka: Keďže zostavy sú kumulatívne, každé nové vydanie opravy obsahuje všetky rýchle opravy a všetky opravy zabezpečenia, ktoré boli súčasťou predchádzajúceho vydania opravy SQL Servera 2008 R2. Odporúčame vám zvážiť použitie najnovšieho vydania opravy, ktoré obsahuje túto opravu. Ďalšie informácie nájdete v článku databázy Microsoft Knowledge Base, ktorý sa zobrazí po kliknutí na príslušné číslo článku:
2567616Zostavy SQL Servera 2008 R2, ktoré boli vydané po vydaní balíka SQL Server 2008 R2 Service Pack 1
Alternatívne riešenie
Spoločnosť Microsoft odporúča, aby ste v dotazoch nepoužívajte niektorú z týchto funkcií v prípade, že sú v nich uvedené paralelné plány, pretože nie sú vždy spoľahlivé. Namiesto toho použite klauzulu OUTPUT príkazu INSERT na načítanie hodnoty identity, ako je znázornené v nižšie uvedenom príklade.
Príklad použitia klauzuly OUTPUT:
DECLARE @MyNewIdentityValues table(myidvalues int)
declare @A table (ID int primary key) vložiť do @A hodnoty (1) declare @B table (ID int primary key identity(1;1); B int not null) vložiť do @B hodnoty (1) vyberte položku [RowCount] = @@RowCount, [@@IDENTITY] = @@IDENTITY; [SCOPE_IDENTITY] = SCOPE_IDENTITY() nastaviť profil štatistiky na vložiť do _ddr_T výstup inserted.ID do @MyNewIdentityValues vyberte položku b.ID z @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 kde neexistuje (vyberte * z _ddr_T t2, kde t2.ID = -1) set statistics profile off vyberte položku [RowCount] = @@RowCount, [@@IDENTITY] = @@IDENTITY; [SCOPE_IDENTITY] = SCOPE_IDENTITY(), [IDENT_CURRENT] = IDENT_CURRENT('_ddr_T') vyberte * v @MyNewIdentityValues prejsťAk vaša situácia vyžaduje, aby ste potrebovali použiť niektorú z týchto funkcií, môžete na alternatívne riešenie problému použiť niektorú z nasledujúcich metód.
Metóda 1:
Zahrnutie nasledujúcej možnosti do dotazu
OPTION (MAXDOP 1)
Poznámka:Môže to uškodiť výkon časti dotazu SELECT.
Metóda 2:
Prečítajte si hodnotu z časti SELECT do množiny premenných (alebo jednej premennej tabuľky) a potom ju vložte do cieľovej tabuľky s MAXDOP =1. Keďže plán INSERT nebude paralelne, získate správny sémantický, ale výber bude paralelne k požadovanému výkonu.
Metóda 3:
Spustením nasledujúceho prehlásenia nastavte maximálny stupeň rovnobežnosti na hodnotu 1:
sp_configure "maximálny stupeň rovnobežnosti", 1
prejsť
prekonfigurovať s prepisom
prejsť
Poznámka:Táto metóda môže spôsobiť zníženie výkonu na serveri. Túto metódu by ste nemali používať, pokiaľ ste ju nevyhodnocovala pri testovaní alebo štúdii prostredia.