Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

IDENT_CURRENT vs @@IDENTITY vs SCOPE_IDENTITY w SQL Server:jaka jest różnica?

W SQL Server, jeśli kiedykolwiek będziesz musiał zwrócić wartość utworzoną w kolumnie tożsamości, masz kilka opcji. Każda z tych opcji, chociaż podobna, działa nieco inaczej.

W szczególności możesz korzystać z następujących funkcji:

  • IDENT_CURRENT() zwraca ostatnio wstawioną wartość tożsamości dla danej tabeli.
  • SCOPE_IDENTITY() zwraca ostatnią wartość tożsamości wstawioną do kolumny tożsamości w any tabela w bieżącej sesji i bieżącym zakresie.
  • @@IDENTITY zwraca ostatnio wstawioną wartość tożsamości w dowolny tabeli w bieżącej sesji, niezależnie od zakresu.

Przykład

Oto przykład, który pokazuje różnicę między tymi trzema funkcjami.

Najpierw utwórz dwie tabele. Zwróć uwagę na różne wartości początkowe i przyrostowe używane w kolumnie tożsamości w każdej tabeli:

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

Teraz utwórz wyzwalacz, który wstawia wiersz do drugiej tabeli za każdym razem, gdy wiersz jest wstawiany do pierwszej tabeli:

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

Wyzwalacze działają w innym zakresie, więc jest to idealne rozwiązanie dla mojego przykładu tutaj.

Wstaw dane do pierwszej tabeli, a następnie wybierz wyniki z obu tabel:

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

Wynik:

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

Żeby było jasne, te dane zostały wprowadzone przez dwa różne zakresy. Wstawka do t1 zostało wykonane według obecnego zakresu. Wstawka do t2 zostało wykonane przez wyzwalacz, który działał w innym zakresie.

Teraz wybierzmy spośród wcześniej wspomnianych funkcji:

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

Wynik:

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

Wynik zwrócony przez @@IDENTITY nie jest ograniczony do zakresu, dlatego zwraca ostatnio wstawioną wartość tożsamości, niezależnie od zakresu.

SCOPE_IDENTITY() zwraca wartość tożsamości z pierwszej tabeli, ponieważ była to ostatnia wstawiona wartość tożsamości w bieżącym zakresie (wyzwalacz jest poza bieżącym zakresem).

IDENT_CURRENT() funkcja po prostu zwraca ostatnią wartość tożsamości wstawioną do określonej tabeli, niezależnie od zakresu lub sesji.

Otwórz nową sesję

A oto co się stanie, jeśli otworzę nową sesję i ponownie uruchomię poprzednią instrukcję:

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

Wynik:

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

Oba @@IDENTITY i SCOPE_IDENTITY() są NULL, ponieważ zwracają tylko wyniki z bieżącej sesji. Nie wykonałem żadnych wstawień kolumn tożsamości w tej nowej sesji, więc otrzymuję NULL.

IDENT_CURRENT() z drugiej strony zwraca ten sam wynik, co w poprzednim przykładzie, ponieważ jego wyniki są oparte na określonej tabeli, niezależnie od sesji lub zakresu.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Co to jest LEN() w SQL Server?

  2. Najszybszy sposób na znalezienie przestarzałych funkcji, które są nadal używane w wystąpieniu programu SQL Server (przykład T-SQL)

  3. Nie używaj sys.sql_dependencies w SQL Server (jest przestarzały)

  4. Zwróć uprawnienia kolumny z serwera połączonego w programie SQL Server (przykłady T-SQL)

  5. Jak migrować zadania SQL Server z jednej instancji SQL Server do innej?