sql >> Databasteknik >  >> RDS >> Sqlserver

Använd SCOPE_IDENTITY() för att returnera det senast infogade identitetsvärdet i samma omfattning (SQL-server)

I SQL Server kan du använda T-SQL SCOPE_IDENTITY() funktion för att returnera det senaste identitetsvärdet som infogats i en identitetskolumn i samma omfång.

En scope är en modul (lagrad procedur, trigger, funktion eller batch). Om två satser är i samma lagrade procedur, funktion eller batch, är de i samma omfång.

Observera att det returnerar det senast genererade identitetsvärdet i valfri tabell i den aktuella sessionen . Detta är i motsats till IDENT_CURRENT() funktion, som returnerar det senast infogade identitetsvärdet för en given tabell , oavsett vilken session den är i.

SCOPE_IDENTITY() är mycket lik @@IDENTITY genom att de båda returnerar det senast infogade identitetsvärdet i den aktuella sessionen. Skillnaden är att SCOPE_IDENTITY() är begränsad till det aktuella omfånget, medan @@IDENTITY är inte begränsad till ett specifikt omfång.

Exempel 1 – Grundläggande användning

Här är ett grundläggande kodexempel på hur det fungerar.

SELECT SCOPE_IDENTITY() AS [Last-Inserted Identity Value];

Resultat:

+--------------------------------+
| Last-Inserted Identity Value   |
|--------------------------------|
| NULL                           |
+--------------------------------+

Anledningen till NULL-resultatet är att jag körde satsen direkt efter att jag öppnat en ny anslutning till SQL Server. SCOPE_IDENTITY() funktion returnerar endast resultat från den aktuella sessionen.

Så för att få ett resultat som inte är NULL måste jag infoga ett värde i en identitetskolumn.

Exempel 2 – Infoga ett värde för ett resultat som inte är NULL

I det här exemplet skapar jag en tabell med en identitetskolumn. Jag infogar sedan ett standardvärde i den tabellen innan jag väljer innehållet i tabellen och kör sedan 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 en rad och dess identitetskolumn har värdet 1. Detta är det senast infogade identitetsvärdet för den aktuella sessionen, och därför SCOPE_IDENTITY() returnerar också 1.

Om jag nu lägger till ytterligare en rad, ökar värdet i enlighet med detta:

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)

Resultat från en ny session

Som nämnts, SCOPE_IDENTITY() returnerar endast resultat från samma session. Detta gäller även för @@IDENTITY .

Så om jag öppnar en ny anslutning till SQL Server och kör den tidigare SELECT påståenden igen får jag följande resultat:

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)

Låt oss nu infoga en ny rad från denna nya 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 kom ikapp så fort jag infogade ett nytt identitetsvärde.

Men låt oss byta tillbaka till den ursprungliga sessionen och köra SELECT uttalanden igen (utan att infoga en ny rad):

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 ursprungliga sessionens SCOPE_IDENTITY() resultaten har inte påverkats av den andra sessionen.

Lägga till ett andra omfång

Det som skiljer SCOPE_IDENTITY() åt från @@IDENTITY , är det SCOPE_IDENTITY() begränsas till nuvarande omfattning.

Om tabellen till exempel har en utlösare som infogar ett identitetsvärde i en annan tabell, SCOPE_IDENTITY() skulle bara rapportera det första identitetsvärdet. Den skulle ignorera identitetsvärdet för den andra tabellen, eftersom den skapades i ett annat omfång @@IDENTITY skulle å andra sidan rapportera identitetsvärdet för den andra tabellen (eftersom den täcker alla omfång).

För ett exempel på vad jag menar, se IDENT_CURRENT vs @@IDENTITY vs SCOPE_IDENTITY i SQL Server:Vad är skillnaden?

Den artikeln går igenom ett triggerexempel som det jag pratar om här.


  1. Hur migrerar man en befintlig Postgres-tabell till en partitionerad tabell så transparent som möjligt?

  2. Hantera Connection Pooling i multi-tenant webbapp med Spring, Hibernate och C3P0

  3. 7 sätt att hitta dubbletter av rader i SQL Server samtidigt som du ignorerar en primärnyckel

  4. Importera "xml" till SQL Server