Gibt es eine Möglichkeit zu sehen, wie SQL Server 2012 neue Identitäten definiert?

7

Gibt Microsoft SQL Server 2012 (SP1) - 11.0.3000.0 (X64)es eine Möglichkeit zu sehen, welchen Mechanismus SQL Server verwendet, um die neuen Identitätswerte für Tabellen zu berechnen, die von erstellt wurden SELECT INTO?


BEISPIELDATEN

-- Create our base table
CREATE TABLE dbo.A
(A_ID INT IDENTITY(1, 1),
x1 INT,
noise1 int DEFAULT 1,
noise2 char(1) DEFAULT 'S',
noise3 date DEFAULT GETUTCDATE(),
noise4 bit DEFAULT 0);

-- Create random data between the range of [0-3]
INSERT INTO dbo.A(x1)
SELECT s1000.n FROM
( SELECT TOP (10) n = 1 FROM sys.columns) AS s10 -- 10
CROSS JOIN
( SELECT TOP (10) n = 1 FROM sys.columns) AS s100 -- 10 * 10
CROSS JOIN
( SELECT TOP (10) n = ABS(CHECKSUM(NEWID())) % 4 FROM sys.columns) AS s1000; -- 100 * 10

SELECT * FROM dbo.A ORDER BY A_ID DESC;

In meinem Fall sind die Ergebnisse:

dbo.A Ergebnisse

Und läuft

DBCC CHECKIDENT('A')

kehrt zurück

Identitätsinformationen prüfen: aktueller Identitätswert '1000', aktueller Spaltenwert '1000'.


Neue Tabelle erstellen

Wenn wir eine Teilmenge in einer neuen Tabelle auswählen, wird ein neuer aktueller Identitätswert erstellt:

SELECT * INTO #temp FROM dbo.A WHERE x1 = 0;

Der höchste Wert in der Identitätsspalte dieser neuen Tabelle ist 998, und wenn wir die nächste Identität überprüfen:

DBCC CHECKIDENT('#temp')

Identitätsinformationen prüfen: aktueller Identitätswert '998', aktueller Spaltenwert '998'.


Wie?

Wie werden diese Identitätswerte in die neue Tabelle eingefügt, wobei der höchste Wert korrekt als aktueller Identitätswert der neuen Tabelle festgelegt wird?

Shaneis
quelle

Antworten:

14

SELECT INTO hat zwei Phasen (in Ausführungsplänen nicht sichtbar).

Zunächst wird eine Tabelle erstellt, die mit den Metadaten der Abfrage übereinstimmt, mit der sie erstellt wurde. Dies geschieht in einer Systemtransaktion, sodass die (leere) erstellte Tabelle auch dann weiterhin vorhanden ist, wenn sie SELECT INTOin eine Benutzertransaktion eingeschlossen ist, die zurückgesetzt wird. Am Ende der ersten Phase haben wir eine leere Tabelle, die eine Spalte mit dem Namen A_ID mit der Identitätseigenschaft enthält.

In der zweiten Phase wird die erste erstellte Phase in die Tabelle eingefügt. Diese Einfügung erfolgt mit der Semantik identity_insert , sodass die Identitätswerte aus der Quelltabelle unverändert im Ziel landen. Der höchste tatsächlich eingefügte Wert wird als zuletzt verwendeter Wert festgelegt. Sie können IDENT_CURRENToder sys.indentity_columns verwenden , um es anzuzeigen .

Nicht verwandte, aber halbinteressante Tatsache: Zwischen dem Erstellen der Tabelle und dem Beginn des Einfügens besteht ein kleines Fenster, in dem die Quelltabelle in der Abfrage nicht durch eine Schemastabilitätssperre geschützt ist. Wenn ein gleichzeitiger Prozess das Schema der Quelltabelle ändert (nachdem das Ziel erstellt wurde, aber bevor das Einfügen beginnt), wird der Fehler 539 ausgelöst:

Das Schema wurde geändert, nachdem die Zieltabelle erstellt wurde. Führen Sie die Abfrage Auswählen in erneut aus.

Paul White 9
quelle