Qual è la differenza tra Scope_Identity (), Identity (), @@ Identity e Ident_Current ()?


192

Lo so Scope_Identity(), Identity(), @@Identity, e Ident_Current()tutto ottenere il valore della colonna di identità, ma mi piacerebbe sapere la differenza.

Parte della controversia che sto affrontando è cosa significano per ambito applicato a queste funzioni sopra?

Mi piacerebbe anche un semplice esempio di diversi scenari di utilizzo?


2
Non dimenticare il bug di esecuzione parallela che esiste in SQL Server per SCOPE_IDENTITY e @@ IDENTITY: support.microsoft.com/default.aspx?scid=kb;en-US;2019779
David d C e Freitas

@DaviddCeFreitas - Sono curioso di leggere del bug, ma il collegamento sembra essere rotto (o almeno, sta generando un errore ASP).
rory.ap,

2
In realtà, l'ho trovato: support.microsoft.com/en-us/kb/2019779
rory.ap

Fix era stato rilasciato come menzionato in quel vecchio articolo di KB
George Birbilis l'

Risposte:


396
  • La @@identityfunzione restituisce l'ultima identità creata nella stessa sessione.
  • La scope_identity()funzione restituisce l'ultima identità creata nella stessa sessione e nello stesso ambito.
  • L' ident_current(name)restituisce l'ultimo identità creata per una specifica tabella o vista in qualsiasi sessione.
  • La identity()funzione non viene utilizzata per ottenere un'identità, viene utilizzata per creare un'identità in una select...intoquery.

La sessione è la connessione al database. L'ambito è la query corrente o la procedura memorizzata corrente.

Una situazione in cui l' scope_identity()e le @@identityfunzioni differiscono, è se si dispone di un trigger sul tavolo. Se si dispone di una query che inserisce un record, causando l'inserimento da parte del trigger di un altro record da qualche parte, la scope_identity()funzione restituirà l'identità creata dalla query, mentre la @@identityfunzione restituirà l'identità creata dal trigger.

Quindi, normalmente useresti la scope_identity()funzione.


14
Ho scelto questa come risposta, a causa del paragrafo "Una situazione in cui scope_identity () e @@ identità ...". Ha chiarito di più le cose.
Tebo,

1
Come ha detto David Freitas sopra, c'è un bug nell'implementazione di scope_identity, quindi raccomando di usare un metodo alternativo, la clausola OUTPUT. Vedi la mia risposta qui sotto.
Sebastian Meine,

@Guffa - "La sessione è la connessione al database". La sessione viene mantenuta tra le connessioni se si utilizza il pool di connessioni?
Dave Black,

1
Questa è una risposta del modello di ruolo. In particolare, lavorare con SQL e SQL Server può essere strano, e questo spiega le cose in un modo molto chiaro, profano, pur essendo abbastanza informativo. Non sembra qualcosa che viene comunicato tra due specialisti di database, cosa che fanno MOLTE altre risposte SE.
Panzercrisis,

@DaveBlack da quello che ho letto: No, la sessione non viene mantenuta nel pool, la sessione è unica per l'esecuzione dello script dopo connect (). Durante il pooling ... PHP per SQL Server utilizza il pool di connessioni ODBC. Quando viene utilizzata una connessione dal pool, lo stato della connessione viene ripristinato. La chiusura della connessione restituisce la connessione al pool. (nota: vedere le osservazioni per linux / mac) docs.microsoft.com/en-us/sql/connect/php/…
GDmac

42

Buona domanda.

  • @@IDENTITY: restituisce l'ultimo valore di identità generato sulla tua connessione SQL (SPID). Il più delle volte sarà quello che vuoi, ma a volte no (come quando un trigger viene attivato in risposta a un INSERT, e il trigger esegue un'altra INSERTistruzione).

  • SCOPE_IDENTITY(): restituisce l'ultimo valore di identità generato nell'ambito corrente (ad es. procedura memorizzata, trigger, funzione, ecc.).

  • IDENT_CURRENT(): restituisce l'ultimo valore di identità per una tabella specifica. Non utilizzarlo per ottenere il valore dell'identità da un INSERT, è soggetto alle condizioni di gara (ovvero connessioni multiple che inseriscono righe nella stessa tabella).

  • IDENTITY(): utilizzato quando si dichiara una colonna in una tabella come colonna identità.

Per ulteriori riferimenti, vedere: http://msdn.microsoft.com/en-us/library/ms187342.aspx .

Per riassumere: se si sta inserendo le righe, e si desidera conoscere il valore della colonna di identità per la riga che si appena inserito, utilizzare sempre SCOPE_IDENTITY().


16

Se capisci la differenza tra ambito e sessione, sarà molto facile capire questi metodi.

Un bellissimo post sul blog di Adam Anderson descrive questa differenza:

Sessione indica la connessione corrente che sta eseguendo il comando.

Scope indica il contesto immediato di un comando. Ogni chiamata di procedura memorizzata viene eseguita nel proprio ambito e le chiamate nidificate vengono eseguite in un ambito nidificato nell'ambito della procedura di chiamata. Allo stesso modo, un comando SQL eseguito da un'applicazione o SSMS viene eseguito nel proprio ambito e, se quel comando attiva qualsiasi trigger, ciascun trigger viene eseguito all'interno del proprio ambito nidificato.

Pertanto, le differenze tra i tre metodi di recupero dell'identità sono le seguenti:

@@identityrestituisce l'ultimo valore di identità generato in questa sessione ma qualsiasi ambito.

scope_identity()restituisce l'ultimo valore di identità generato in questa sessione e in questo ambito.

ident_current()restituisce l'ultimo valore Identity generato per una particolare tabella in qualsiasi sessione e qualsiasi ambito.


11

Per ambito si intende il contesto del codice che esegue l' INSERTistruzione SCOPE_IDENTITY(), al contrario dell'ambito globale di @@IDENTITY.

CREATE TABLE Foo(
  ID INT IDENTITY(1,1),
  Dummy VARCHAR(100)
)

CREATE TABLE FooLog(
  ID INT IDENTITY(2,2),
  LogText VARCHAR(100)
)
go
CREATE TRIGGER InsertFoo ON Foo AFTER INSERT AS
BEGIN
  INSERT INTO FooLog (LogText) VALUES ('inserted Foo')
  INSERT INTO FooLog (LogText) SELECT Dummy FROM inserted
END

INSERT INTO Foo (Dummy) VALUES ('x')
SELECT SCOPE_IDENTITY(), @@IDENTITY 

Dà risultati diversi.


6

Per chiarire il problema con @@Identity:

Ad esempio, se si inserisce una tabella e quella tabella ha trigger che eseguono inserimenti, @@Identityrestituirà l'id dall'inserto nel trigger (a log_ido qualcosa del genere), mentre scope_identity()restituirà l'id dall'inserto nella tabella originale.

Quindi se non hai trigger scope_identity()e @@identityrestituirai lo stesso valore. Se hai i trigger, devi pensare a quale valore desideri.


4

Scope Identity: Identità dell'ultimo record aggiunto nella procedura memorizzata in esecuzione.

@@Identity: Identità dell'ultimo record aggiunto all'interno del batch di query o come risultato della query, ad esempio una procedura che esegue un inserimento, quindi attiva un trigger che quindi inserisce un record restituirà l'identità del record inserito dal trigger.

IdentCurrent: L'ultima identità allocata per la tabella.


3

Ecco un'altra buona spiegazione del libro :

Per quanto riguarda la differenza tra SCOPE_IDENTITY e @@ IDENTITY, supponiamo di avere una procedura memorizzata P1 con tre istruzioni:
- Un INSERT che genera un nuovo valore di identità
- Una chiamata a una procedura memorizzata P2 che ha anche un'istruzione INSERT che genera una nuova valore identità
- Un'istruzione che richiede le funzioni SCOPE_IDENTITY e @@ IDENTITY La funzione SCOPE_IDENTITY restituirà il valore generato da P1 (stessa sessione e ambito). La funzione @@ IDENTITY restituirà il valore generato da P2 (stessa sessione indipendentemente dall'ambito).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.