I SQL Server kan du bruge T-SQL SCOPE_IDENTITY()
funktion til at returnere den sidste identitetsværdi indsat i en identitetskolonne i samme omfang.
Et omfang er et modul (lagret procedure, trigger, funktion eller batch). Hvis to sætninger er i den samme lagrede procedure, funktion eller batch, er de i samme omfang.
Bemærk, at det returnerer den sidst genererede identitetsværdi i enhver tabel i den aktuelle session . Dette er i modsætning til IDENT_CURRENT()
funktion, som returnerer den sidst indsatte identitetsværdi for en given tabel , uanset hvilken session den er i.
SCOPE_IDENTITY()
er meget lig @@IDENTITY
ved at de begge returnerer den sidst indsatte identitetsværdi i den aktuelle session. Forskellen er, at SCOPE_IDENTITY()
er begrænset til det nuværende omfang, hvorimod @@IDENTITY
er ikke begrænset til et specifikt omfang.
Eksempel 1 – Grundlæggende brug
Her er et grundlæggende kodeeksempel på, hvordan det virker.
SELECT SCOPE_IDENTITY() AS [Last-Inserted Identity Value];
Resultat:
+--------------------------------+ | Last-Inserted Identity Value | |--------------------------------| | NULL | +--------------------------------+
Årsagen til NULL-resultatet er, at jeg kørte sætningen umiddelbart efter at have åbnet en ny forbindelse til SQL Server. SCOPE_IDENTITY()
funktion returnerer kun resultater fra den aktuelle session.
Så for at få et resultat, der ikke er NULL, skal jeg indsætte en værdi i en identitetskolonne.
Eksempel 2 – Indsæt en værdi for et resultat, der ikke er NULL
I dette eksempel opretter jeg en tabel med en identitetskolonne. Jeg indsætter derefter en standardværdi i den tabel, før jeg vælger indholdet af tabellen og derefter kører SCOPE_IDENTITY()
igen.
CREATE TABLE scope_identity_test(id int IDENTITY(1,1)); INSERT scope_identity_test DEFAULT VALUES; SELECT id FROM scope_identity_test; SELECT SCOPE_IDENTITY() AS [Last-Inserted Identity Value];
Resultat:
+------+ | id | |------| | 1 | +------+ (1 row affected) +--------------------------------+ | Last-Inserted Identity Value | |--------------------------------| | 1 | +--------------------------------+ (1 row affected)
Tabellen har én række, og dens identitetskolonne har værdien 1. Dette er den sidst indsatte identitetsværdi for den aktuelle session, og derfor SCOPE_IDENTITY()
returnerer også 1.
Hvis jeg tilføjer endnu en række, stiger værdien tilsvarende:
INSERT scope_identity_test DEFAULT VALUES; SELECT id FROM scope_identity_test; SELECT SCOPE_IDENTITY() AS [Last-Inserted Identity Value];
Resultat:
+------+ | id | |------| | 1 | | 2 | +------+ (2 rows affected) +--------------------------------+ | Last-Inserted Identity Value | |--------------------------------| | 2 | +--------------------------------+ (1 row affected)
Resultater fra en ny session
Som nævnt, SCOPE_IDENTITY()
returnerer kun resultater fra samme session. Dette gælder også for @@IDENTITY
.
Så hvis jeg åbner en ny forbindelse til SQL Server og kører den forrige SELECT
udsagn igen, får jeg følgende resultater:
USE Test; SELECT id FROM scope_identity_test; SELECT SCOPE_IDENTITY() AS [Last-Inserted Identity Value];
Resultat:
+------+ | id | |------| | 1 | | 2 | +------+ (2 rows affected) +--------------------------------+ | Last-Inserted Identity Value | |--------------------------------| | NULL | +--------------------------------+ (1 row affected)
Lad os nu indsætte en ny række fra denne nye session:
INSERT scope_identity_test DEFAULT VALUES; SELECT id FROM scope_identity_test; SELECT SCOPE_IDENTITY() AS [Last-Inserted Identity Value];
Resultat:
+------+ | id | |------| | 1 | | 2 | | 3 | +------+ (1 row affected) +--------------------------------+ | Last-Inserted Identity Value | |--------------------------------| | 3 | +--------------------------------+ (3 rows affected)
Så det indhentede, så snart jeg indsatte en ny identitetsværdi.
Lad os dog skifte tilbage til den oprindelige session og køre SELECT
udsagn igen (uden at indsætte en ny række):
SELECT id FROM scope_identity_test; SELECT SCOPE_IDENTITY() AS [Last-Inserted Identity Value];
Resultat:
+------+ | id | |------| | 1 | | 2 | | 3 | +------+ (3 rows affected) +--------------------------------+ | Last-Inserted Identity Value | |--------------------------------| | 2 | +--------------------------------+ (1 row affected)
Så den oprindelige sessions SCOPE_IDENTITY()
resultaterne er ikke blevet påvirket af den anden session.
Tilføjelse af et andet omfang
Det, der adskiller SCOPE_IDENTITY()
fra @@IDENTITY
, er det SCOPE_IDENTITY()
er begrænset til det nuværende anvendelsesområde.
For eksempel, hvis tabellen har en trigger, der indsætter en identitetsværdi i en anden tabel, SCOPE_IDENTITY()
ville kun rapportere den første identitetsværdi. Det ville ignorere identitetsværdien for den anden tabel, fordi den blev oprettet i et andet omfang @@IDENTITY
ville på den anden side rapportere identitetsværdien for den anden tabel (fordi den dækker alle scopes).
For et eksempel på, hvad jeg mener, se IDENT_CURRENT vs @@IDENTITY vs SCOPE_IDENTITY i SQL Server:Hvad er forskellen?
Den artikel gennemgår et trigger-eksempel som det, jeg taler om her.