sql >> Databasteknik >  >> RDS >> Sqlserver

IDENT_CURRENT vs @@IDENTITY vs SCOPE_IDENTITY i SQL Server:Vad är skillnaden?

I SQL Server, om du någonsin behöver returnera värdet som skapats i en identitetskolumn, har du flera alternativ. Vart och ett av dessa alternativ, även om de är lika, gör en något annorlunda sak.

I synnerhet kan du använda följande funktioner:

  • IDENT_CURRENT() returnerar det senast infogade identitetsvärdet för en given tabell.
  • SCOPE_IDENTITY() returnerar det senaste identitetsvärdet som infogats i en identitetskolumn i alla tabell i den aktuella sessionen och aktuellt omfång.
  • @@IDENTITY returnerar det senast infogade identitetsvärdet i alla tabell i den aktuella sessionen, oavsett omfattning.

Exempel

Här är ett exempel som visar skillnaden mellan dessa tre funktioner.

Skapa först två tabeller. Lägg märke till de olika start- och inkrementvärdena som används för identitetskolumnen i varje tabell:

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

Skapa nu en utlösare som infogar en rad i den andra tabellen när en rad infogas i den första tabellen:

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

Utlöser eld i en annan omfattning, så det är perfekt för mitt exempel här.

Infoga data i den första tabellen och välj sedan resultaten från båda tabellerna:

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

Resultat:

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

Så bara för att vara tydlig, denna data infogades med två olika omfattningar. Infogningen i t1 skedde med nuvarande omfattning. Infoga i t2 gjordes av utlösaren, som kördes i en annan omfattning.

Låt oss nu välja bland de funktioner som nämnts tidigare:

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

Resultat:

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

Resultatet returneras av @@IDENTITY är inte begränsad till omfattning, och därför returnerar den det senast infogade identitetsvärdet, oavsett omfattning.

SCOPE_IDENTITY() returnerar identitetsvärdet från den första tabellen, eftersom det var det senast infogade identitetsvärdet inom det aktuella omfånget (utlösaren är utanför det aktuella omfånget).

IDENT_CURRENT() funktion returnerar helt enkelt det senaste identitetsvärdet som infogats i den angivna tabellen, oavsett omfattning eller session.

Öppna en ny session

Nu, här är vad som händer om jag öppnar en ny session och kör det tidigare uttalandet igen:

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

Resultat:

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

Båda @@IDENTITY och SCOPE_IDENTITY() är NULL eftersom de bara returnerar resultat från den aktuella sessionen. Jag har inte infogat någon identitetskolumn i den här nya sessionen, så jag får NULL.

IDENT_CURRENT() å andra sidan, returnerar samma resultat som i föregående exempel, igen eftersom dess resultat baseras på den angivna tabellen, oavsett session eller omfattning.


  1. Tabellen är "skrivskyddad"

  2. Hur man rangordnar rader inom en partition i SQL

  3. MySQL och NoSQL:Hjälp mig att välja rätt

  4. Hur man bara lagrar tid; inte datum och tid?