Příznaky
Pokud k načtení hodnot vkládaných do sloupce identity SCOPE_IDENTITY() nebo @@IDENTITY funkce, můžete si všimnout, že tyto funkce někdy vracejí nesprávné hodnoty. K problému dochází jenom v případě, že dotazy používají plány paralelního spuštění. Další informace o tom, jak zjistit, jestli vaše dotazy budou používat plány paralelního spuštění, najdete v části Paralelnost v rámci dotazu v následujícím technickém článku o stažení microsoftu:
Příčina
Společnost Microsoft potvrdila, že se jedná o problém v produktech společnosti Microsoft, které jsou uvedené na začátku tohoto článku.
Řešení
Informace o kumulativní aktualizaci
SQL Server 2008 R2 Service Pack 1
Oprava tohoto problému byla poprvé vydána v kumulativní aktualizaci 5 pro SQL Server 2008 R2 Service Pack 1. Další informace o tom, jak získat tento balíček kumulativní aktualizace, najdete v následujícím článku znalostní báze Microsoft Knowledge Base:
2659694Balíček kumulativní aktualizace 5 pro SQL Server 2008 R2 Service Pack 1
PoznámkaVzhledem k tomu, že buildy jsou kumulativní, každá nová verze opravy obsahuje všechny opravy hotfix a všechny opravy zabezpečení, které byly součástí předchozího SQL Serveru 2008 R2, opravují verzi. Doporučujeme zvážit použití nejnovější verze opravy, která obsahuje tuto opravu hotfix. Další informace naleznete v následujícím článku znalostní báze Microsoft Knowledge Base:
2567616Buildy SQL Serveru 2008 R2 vydané po vydání SQL Serveru 2008 R2 Service Pack 1
Alternativní řešení
Společnost Microsoft doporučuje, abyste v dotazech nepou ít žádné z těchto funkcí, pokud jsou zapojené paralelní plány, protože nejsou vždy spolehlivé. Místo toho použijte klauzuli OUTPUT příkazu INSERT k načtení hodnoty identity, jak je znázorněno v následujícím příkladu.
Příklad použití klauzule OUTPUT:
DECLARE @MyNewIdentityValues table(myidvalues int)
declare @A table (ID int primary key)
vložení do @A hodnot (1)
declare @B table (ID int primary key identity(1;1), B int not null)
vložení do @B hodnot (1)
vyberte
[RowCount] = @@RowCount;
[@@IDENTITY] = @@IDENTITY;
[SCOPE_IDENTITY] = SCOPE_IDENTITY()
nastavit profil statistiky na
vložení do _ddr_T
výstupní inserted.ID do @MyNewIdentityValues
vyberte
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
where not exists (select * from _ddr_T t2 where t2.ID = -1)
vypnutí statistického profilu
vyberte
[RowCount] = @@RowCount;
[@@IDENTITY] = @@IDENTITY;
[SCOPE_IDENTITY] = SCOPE_IDENTITY(),
[IDENT_CURRENT] = IDENT_CURRENT('_ddr_T')
vyberte * z @MyNewIdentityValues
přejít
Pokud vaše situace vyžaduje, abyste některou z těchto funkcí potřebovali použít, můžete tento problém vyřešit jedním z následujících způsobů.
Metoda 1:
Zahrnutí následující možnosti do dotazu
OPTION (MAXDOP 1)
Poznámka:Může to zranit výkon části dotazu SELECT.
Způsob 2:
Přečtěte si hodnotu z části SELECT do sady proměnných (nebo jedné proměnné tabulky) a potom vložte do cílové tabulky s hodnotou MAXDOP=1. Vzhledem k tomu, že plán INSERT nebude rovnoběžný, získáte správnou sémantiku, ale váš select bude rovnoběžný, aby dosáhl požadovaného výkonu.
Metoda 3:
Spuštěním následujícího příkazu nastavte maximální stupeň rovnoběžnosti na hodnotu 1:
sp_configure "maximální stupeň rovnoběžnosti", 1
přejít
překonfigurovat s přepsáním
přejít
Poznámka:Tato metoda může způsobit snížení výkonu na serveru. Tuto metodu byste neměli používat, pokud jste ji nevyhodnotili v testovacím nebo pracovním prostředí.
Další informace
Chyba Microsoft Connect v tomtohttps://docs.microsoft.com/en-us/collaborate/connect-redirect