sql >> Database teknologi >  >> RDS >> Sqlserver

IDENT_CURRENT vs @@IDENTITY vs SCOPE_IDENTITY i SQL Server:Hvad er forskellen?

I SQL Server, hvis du nogensinde har brug for at returnere den værdi, der er oprettet i en identitetskolonne, har du flere muligheder. Hver af disse muligheder, selvom de ligner hinanden, gør en lidt anderledes ting.

Du kan især bruge følgende funktioner:

  • IDENT_CURRENT() returnerer den sidst indsatte identitetsværdi for en given tabel.
  • SCOPE_IDENTITY() returnerer den sidste identitetsværdi, der er indsat i en identitetskolonne i enhver tabel i den aktuelle session og det aktuelle omfang.
  • @@IDENTITY returnerer den sidst indsatte identitetsværdi i enhver tabel i den aktuelle session, uanset omfang.

Eksempel

Her er et eksempel, der viser forskellen mellem disse tre funktioner.

Først skal du oprette to tabeller. Bemærk de forskellige seed- og stigningsværdier, der bruges til identitetskolonnen i hver tabel:

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

Opret nu en trigger, der indsætter en række i den anden tabel, hver gang en række indsættes i den første tabel:

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

Udløser brand i et andet omfang, så det er perfekt til mit eksempel her.

Indsæt data i den første tabel, og vælg derefter resultaterne fra begge tabeller:

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å bare for at være klar, blev disse data indsat af to forskellige omfang. Indsættet i t1 skete efter det nuværende omfang. Indsættet i t2 blev udført af triggeren, som kørte i et andet omfang.

Lad os nu vælge blandt de tidligere nævnte funktioner:

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 returneret af @@IDENTITY er ikke begrænset til omfang, og derfor returnerer den den sidst indsatte identitetsværdi, uanset omfang.

SCOPE_IDENTITY() returnerer identitetsværdien fra den første tabel, fordi det var den sidst indsatte identitetsværdi inden for det aktuelle omfang (udløseren er uden for det aktuelle omfang).

IDENT_CURRENT() funktion returnerer simpelthen den sidste identitetsværdi, der er indsat i den angivne tabel, uanset omfang eller session.

Åbn en ny session

Her er hvad der sker, hvis jeg åbner en ny session og kører den forrige sætning 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                   |
+--------------+--------------------+-----------------------+-----------------------+

Begge @@IDENTITY og SCOPE_IDENTITY() er NULL, fordi de kun returnerer resultater fra den aktuelle session. Jeg har ikke udført nogen identitetskolonneindsættelser i denne nye session, så jeg får NULL.

IDENT_CURRENT() på den anden side returnerer det samme resultat som i det foregående eksempel, igen fordi dets resultater er baseret på den angivne tabel, uanset session eller omfang.


  1. Returner pre-UPDATE kolonneværdier kun ved brug af SQL

  2. Hvordan fejlfinder man Lås ventetimeout overskredet på MySQL?

  3. Top 10 interessante fakta og tips om MySQL

  4. Hvordan indsætter man data i PostgreSQL med COPY-kommandoen?