Problembeschreibung
Wenn Sie entweder SCOPE_IDENTITY() oder @@IDENTITY zum Abrufen der in eine Identitätsspalte eingefügten Werte verwenden, können Sie feststellen, dass diese Funktionen manchmal falsche Werte zurückgeben. Das Problem tritt nur auf, wenn Ihre Abfragen parallele Ausführungspläne verwenden. Weitere Informationen zum Ermitteln, ob Ihre Abfragen Pläne für die parallele Ausführung verwenden, finden Sie im Abschnitt Abfrageinterne Parallelität im folgenden technischen Artikel zu Microsoft-Downloads:
Ursache
Microsoft hat bestätigt, dass es sich hierbei um ein Problem bei den in diesem Artikel genannten Microsoft-Produkten handelt.
Fehlerbehebung
Informationen zum kumulativen Update
SQL Server 2008 R2 Service Pack 1
Der Fix für dieses Problem wurde zuerst im kumulativen Update 5 für SQL Server 2008 R2 Service Pack 1 veröffentlicht. Wenn Sie weitere Informationen zum Abrufen dieses kumulativen Updatepakets erhalten möchten, klicken Sie auf die folgende Artikelnummer, um den Artikel in der Microsoft Knowledge Base zu sehen:
2659694Kumulatives Updatepaket 5 für SQL Server 2008 R2 Service Pack 1
Hinweis Da die Builds kumuliert sind, enthält jede neue Fixversion alle Hotfixes und alle Sicherheitsfixes, die in der vorherigen Version von SQL Server 2008 R2 Fix Release enthalten waren. Es wird empfohlen, die Anwendung der neuesten Fixversion zu erwägen, die diesen Hotfix enthält. Weitere Informationen finden Sie im folgenden Artikel der Microsoft Knowledge Base:
2567616Die SQL Server 2008 R2-Builds, die nach SQL Server 2008 R2 Service Pack 1 veröffentlicht wurden
Problemumgehung
Microsoft empfiehlt, keine dieser Funktionen in Ihren Abfragen zu verwenden, wenn parallele Pläne einbezogen werden, da sie nicht immer zuverlässig sind. Verwenden Sie stattdessen die OUTPUT-Klausel der INSERT-Anweisung, um den Identitätswert abzurufen, wie im folgenden Beispiel gezeigt.
Beispiel für die Verwendung der OUTPUT-Klausel:
DECLARE @MyNewIdentityValues table(myidvalues int)
Deklarieren @A -Tabelle (ID int-Primärschlüssel) Einfügen in @A Werte (1) deklarieren @B (ID int Primary Key Identity(1;1), B int not null) Einfügen in @B Werte (1) auswählen [RowCount] = @@RowCount, [@@IDENTITY] = @@IDENTITY, [SCOPE_IDENTITY] = SCOPE_IDENTITY() Festlegen des Statistikprofils für Einfügen in _ddr_T Ausgabe inserted.ID in @MyNewIdentityValues auswählen b.ID aus @A Linke Verknüpfung @B b auf b.ID = 1 links an @B b2 auf b2 teilnehmen. B = -1 Linksverteiler _ddr_T t auf t.T = -1 wo nicht vorhanden ist (wählen Sie * aus _ddr_T t2 aus, t2.ID = -1) Festlegen des Statistikprofils auswählen [RowCount] = @@RowCount, [@@IDENTITY] = @@IDENTITY, [SCOPE_IDENTITY] = SCOPE_IDENTITY(), [IDENT_CURRENT] = IDENT_CURRENT('_ddr_T') wählen Sie * aus @MyNewIdentityValues Gehe zuWenn Sie in Ihrer Situation eine dieser Funktionen verwenden müssen, können Sie eine der folgenden Methoden verwenden, um das Problem zu umgehen.
Methode 1:
Hinzufügen der folgenden Option in ihre Abfrage
WAHL (MAXDOP 1)
Hinweis:Dies kann die Leistung des SELECT-Teils Ihrer Abfrage beeinträchtigen.
Methode 2:
Lesen Sie den Wert aus dem TEIL SELECT in eine Gruppe von Variablen (oder eine einzelne Tabellenvariable), und fügen Sie dann mit MAXDOP=1 in die Zieltabelle ein. Da der INSERT-Plan nicht parallel ist, erhalten Sie die richtige Semantik, aber Ihr SELECT wird parallel ausgeführt, um die gewünschte Leistung zu erzielen.
Methode 3:
Führen Sie die folgende Anweisung aus, um den maximalen Grad der Parallelität auf 1 zu setzen:
sp_configure "Max. Grad der Parallelität", 1
Gehe zu
Neukonfigurieren mit Überschreibung
Gehe zu
Hinweis:Diese Methode kann zu Leistungseinbußen auf dem Server führen. Sie sollten diese Methode nur verwenden, wenn Sie sie in einer Testumgebung oder in einer Stagingumgebung ausgewertet haben.
Weitere Informationen
Microsoft #A0 zu diesem Problemhttps://docs.microsoft.com/en-us/collaborate/connect-redirect