sql >> Database >  >> RDS >> Sqlserver

IDENT_CURRENT vs @@IDENTITY vs SCOPE_IDENTITY in SQL Server:wat is het verschil?

Als u in SQL Server ooit de waarde die in een identiteitskolom is gemaakt, moet retourneren, hebt u verschillende opties. Elk van deze opties, hoewel vergelijkbaar, doet iets anders.

U kunt in het bijzonder de volgende functies gebruiken:

  • IDENT_CURRENT() geeft de laatst ingevoerde identiteitswaarde voor een bepaalde tabel terug.
  • SCOPE_IDENTITY() retourneert de laatste identiteitswaarde die is ingevoegd in een identiteitskolom in elke tabel in de huidige sessie en het huidige bereik.
  • @@IDENTITY geeft de laatst ingevoerde identiteitswaarde terug in elke tabel in de huidige sessie, ongeacht het bereik.

Voorbeeld

Hier is een voorbeeld dat het verschil tussen deze drie functies laat zien.

Maak eerst twee tabellen. Let op de verschillende seed- en incrementwaarden die worden gebruikt voor de identiteitskolom in elke tabel:

CREATE TABLE t1(id int IDENTITY(1,1));  
CREATE TABLE t2(id int IDENTITY(150,10));

Maak nu een trigger die een rij invoegt in de tweede tabel wanneer een rij in de eerste tabel wordt ingevoegd:

CREATE TRIGGER t1_insert_trigger ON t1 FOR INSERT
AS
BEGIN
  INSERT t2 DEFAULT VALUES
END;

Activeert vuur in een ander bereik, dus dat is perfect voor mijn voorbeeld hier.

Voeg gegevens in de eerste tabel in en selecteer vervolgens de resultaten uit beide tabellen:

INSERT t1 DEFAULT VALUES;
SELECT id AS t1 FROM t1;
SELECT id AS t2 FROM t2;

Resultaat:

+------+
| t1   |
|------|
| 1    |
+------+
(1 row affected)
+------+
| t2   |
|------|
| 150  |
+------+
(1 row affected)

Dus voor de duidelijkheid, deze gegevens zijn ingevoegd door twee verschillende scopes. Het invoegen in t1 gedaan met de huidige scope. Het invoegen in t2 werd gedaan door de trigger, die in een ander bereik liep.

Laten we nu een keuze maken uit de eerder genoemde functies:

SELECT 
  @@IDENTITY AS [@@IDENTITY],
  SCOPE_IDENTITY() AS [SCOPE_IDENTITY()],
  IDENT_CURRENT('t1') AS [IDENT_CURRENT('t1')],
  IDENT_CURRENT('t2') AS [IDENT_CURRENT('t2')];

Resultaat:

+--------------+--------------------+-----------------------+-----------------------+
| @@IDENTITY   | SCOPE_IDENTITY()   | IDENT_CURRENT('t1')   | IDENT_CURRENT('t2')   |
|--------------+--------------------+-----------------------+-----------------------|
| 150          | 1                  | 1                     | 150                   |
+--------------+--------------------+-----------------------+-----------------------+

Het resultaat geretourneerd door @@IDENTITY is niet beperkt tot bereik en retourneert daarom de laatst ingevoegde identiteitswaarde, ongeacht het bereik.

SCOPE_IDENTITY() retourneert de identiteitswaarde uit de eerste tabel, omdat dat de laatste ingevoegde identiteitswaarde was binnen het huidige bereik (de trigger valt buiten het huidige bereik).

De IDENT_CURRENT() functie retourneert eenvoudig de laatste identiteitswaarde die in de opgegeven tabel is ingevoegd, ongeacht het bereik of de sessie.

Open een nieuwe sessie

Dit is wat er gebeurt als ik een nieuwe sessie open en de vorige instructie opnieuw uitvoer:

USE Test;
SELECT 
  @@IDENTITY AS [@@IDENTITY],
  SCOPE_IDENTITY() AS [SCOPE_IDENTITY()],
  IDENT_CURRENT('t1') AS [IDENT_CURRENT('t1')],
  IDENT_CURRENT('t2') AS [IDENT_CURRENT('t2')];

Resultaat:

+--------------+--------------------+-----------------------+-----------------------+
| @@IDENTITY   | SCOPE_IDENTITY()   | IDENT_CURRENT('t1')   | IDENT_CURRENT('t2')   |
|--------------+--------------------+-----------------------+-----------------------|
| NULL         | NULL               | 1                     | 150                   |
+--------------+--------------------+-----------------------+-----------------------+

Beide @@IDENTITY en SCOPE_IDENTITY() zijn NULL omdat ze alleen resultaten van de huidige sessie retourneren. Ik heb geen identiteitskolommen ingevoegd in deze nieuwe sessie, dus ik krijg NULL.

IDENT_CURRENT() aan de andere kant retourneert hetzelfde resultaat als in het vorige voorbeeld, opnieuw omdat de resultaten zijn gebaseerd op de opgegeven tabel, ongeacht de sessie of het bereik.


  1. Hoe detecteer je dat de transactie al is gestart?

  2. Hoe werk ik met zeer nauwkeurige decimalen in PHP

  3. MySQL INSERT- of REPLACE-opdrachten

  4. Fix "datum is incompatibel met int" in SQL Server bij toevoegen aan of aftrekken van een datum