sql >> Database >  >> RDS >> Sqlserver

Gebruik SCOPE_IDENTITY() om de laatst ingevoerde identiteitswaarde in hetzelfde bereik te retourneren (SQL-server)

In SQL Server kunt u de T-SQL SCOPE_IDENTITY() . gebruiken functie om de laatste identiteitswaarde te retourneren die in een identiteitskolom in hetzelfde bereik is ingevoegd.

Een scope is een module (opgeslagen procedure, trigger, functie of batch). Als twee instructies zich in dezelfde opgeslagen procedure, functie of batch bevinden, vallen ze in hetzelfde bereik.

Merk op dat het de laatste identiteitswaarde retourneert die is gegenereerd in elke tabel in de huidige sessie . Dit in tegenstelling tot de IDENT_CURRENT() functie, die de laatst ingevoerde identiteitswaarde retourneert voor een bepaalde tabel , ongeacht in welke sessie het is.

SCOPE_IDENTITY() lijkt erg op @@IDENTITY in die zin dat ze allebei de laatst ingevoerde identiteitswaarde in de huidige sessie retourneren. Het verschil is dat SCOPE_IDENTITY() is beperkt tot het huidige bereik, terwijl @@IDENTITY is niet beperkt tot een specifiek bereik.

Voorbeeld 1 – Basisgebruik

Hier is een eenvoudig codevoorbeeld van hoe het werkt.

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

Resultaat:

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

De reden voor het NULL-resultaat is omdat ik de instructie onmiddellijk na het openen van een nieuwe verbinding met SQL Server heb uitgevoerd. De SCOPE_IDENTITY() functie retourneert alleen resultaten van de huidige sessie.

Dus om een ​​niet-NULL-resultaat te krijgen, moet ik een waarde invoegen in een identiteitskolom.

Voorbeeld 2 – Voer een waarde in voor een niet-NULL-resultaat

In dit voorbeeld maak ik een tabel met een identiteitskolom. Ik voeg vervolgens een standaardwaarde in die tabel in voordat ik de inhoud van de tabel selecteer en vervolgens SCOPE_IDENTITY() uitvoert nogmaals.

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];

Resultaat:

+------+
| id   |
|------|
| 1    |
+------+
(1 row affected)
+--------------------------------+
| Last-Inserted Identity Value   |
|--------------------------------|
| 1                              |
+--------------------------------+
(1 row affected)

De tabel heeft één rij en de identiteitskolom heeft de waarde 1. Dit is de laatst ingevoerde identiteitswaarde voor de huidige sessie, en dus SCOPE_IDENTITY() geeft ook 1 terug.

Als ik nu nog een rij toevoeg, wordt de waarde overeenkomstig verhoogd:

INSERT scope_identity_test DEFAULT VALUES;
SELECT id FROM scope_identity_test;
SELECT SCOPE_IDENTITY() AS [Last-Inserted Identity Value];

Resultaat:

+------+
| id   |
|------|
| 1    |
| 2    |
+------+
(2 rows affected)
+--------------------------------+
| Last-Inserted Identity Value   |
|--------------------------------|
| 2                              |
+--------------------------------+
(1 row affected)

Resultaten van een nieuwe sessie

Zoals vermeld, SCOPE_IDENTITY() retourneert alleen resultaten van dezelfde sessie. Dit geldt ook voor @@IDENTITY .

Dus als ik een nieuwe verbinding met SQL Server open en de vorige SELECT . uitvoer, verklaringen nogmaals, krijg ik de volgende resultaten:

USE Test;
SELECT id FROM scope_identity_test;
SELECT SCOPE_IDENTITY() AS [Last-Inserted Identity Value];

Resultaat:

+------+
| id   |
|------|
| 1    |
| 2    |
+------+
(2 rows affected)
+--------------------------------+
| Last-Inserted Identity Value   |
|--------------------------------|
| NULL                           |
+--------------------------------+
(1 row affected)

Laten we nu een nieuwe rij invoegen vanuit deze nieuwe sessie:

INSERT scope_identity_test DEFAULT VALUES;
SELECT id FROM scope_identity_test;
SELECT SCOPE_IDENTITY() AS [Last-Inserted Identity Value];

Resultaat:

+------+
| id   |
|------|
| 1    |
| 2    |
| 3    |
+------+
(1 row affected)
+--------------------------------+
| Last-Inserted Identity Value   |
|--------------------------------|
| 3                              |
+--------------------------------+
(3 rows affected)

Dus het werd ingehaald zodra ik een nieuwe identiteitswaarde invoerde.

Laten we echter teruggaan naar de oorspronkelijke sessie en de SELECT . uitvoeren instructies opnieuw (zonder een nieuwe rij in te voegen):

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

Resultaat:

+------+
| id   |
|------|
| 1    |
| 2    |
| 3    |
+------+
(3 rows affected)
+--------------------------------+
| Last-Inserted Identity Value   |
|--------------------------------|
| 2                              |
+--------------------------------+
(1 row affected)

Dus de originele sessie is SCOPE_IDENTITY() resultaten zijn niet beïnvloed door de tweede sessie.

Een tweede bereik toevoegen

Het ding dat SCOPE_IDENTITY() onderscheidt van @@IDENTITY , is dat SCOPE_IDENTITY() beperkt tot het huidige bereik.

Als de tabel bijvoorbeeld een trigger heeft die een identiteitswaarde in een andere tabel invoegt, SCOPE_IDENTITY() zou alleen de eerste identiteitswaarde rapporteren. Het zou de identiteitswaarde voor de tweede tabel negeren, omdat die in een ander bereik is gemaakt @@IDENTITY aan de andere kant, zou de identiteitswaarde voor de tweede tabel rapporteren (omdat deze alle bereiken dekt).

Voor een voorbeeld van wat ik bedoel, zie IDENT_CURRENT vs @@IDENTITY vs SCOPE_IDENTITY in SQL Server:Wat is het verschil?

Dat artikel loopt door een triggervoorbeeld zoals waar ik het hier over heb.


  1. Verkrijg de records van de afgelopen maand in SQL-server

  2. Heroku Postgres:Te veel verbindingen. Hoe vernietig ik deze verbindingen?

  3. Scheidingsteken voor duizendtallen in SQL Server 2008 voor een kolom

  4. Hoe meerdere records in te voegen en de identiteitswaarde te krijgen?