2009-12-17 23 views
96

I so Scope_Identity(), Identity(), @@Identity e Ident_Current() ottengono tutti il ​​valore della colonna Identity, ma mi piacerebbe sapere la differenza.Qual è la differenza tra Scope_Identity(), Identity(), @@ Identity e Ident_Current()?

Parte della controversia che sto avendo è cosa intendono per ambito applicato a queste funzioni sopra?

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

+2

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

+0

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

+1

In realtà, l'ho trovato: https://support.microsoft.com/en-us/kb/2019779 –

risposta

218
  • La funzione @@identity restituisce l'ultima identità creata nella stessa sessione.
  • La funzione scope_identity() restituisce l'ultimo identità creata nella stessa sessione e la stessa portata.
  • Il ident_current(name) restituisce l'ultima identità creata per una tabella o vista specifica in qualsiasi sessione.
  • La funzione identity() non viene utilizzata per ottenere un'identità, viene utilizzata per creare un'identità in una query select...into.

La sessione è la connessione al database. L'ambito è la query corrente o la stored procedure corrente.

Una situazione in cui le funzioni scope_identity() e @@identity differiscono, è se si dispone di un trigger sulla tabella. Se hai una query che inserisce un record, facendo in modo che il trigger inserisca un altro record da qualche parte, la funzione scope_identity() restituirà l'identità creata dalla query, mentre la funzione @@identity restituirà l'identità creata dal trigger.

Quindi, Normalmente si dovrebbe utilizzare la funzione scope_identity().

+5

+1 Molto esplicativo. – Tebo

+9

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

+1

Come menzionato in precedenza da David Freitas, c'è un bug nell'implementazione di scope_identity, quindi consiglio di utilizzare un metodo alternativo, la clausola OUTPUT. Vedi la mia risposta qui sotto. –

34

Buona domanda.

  • @@IDENTITY: restituisce il valore di identità ultima generato sulla vostra connessione SQL (SPID). Il più delle volte sarà ciò che desideri, ma a volte non lo è (come quando viene attivato un trigger in risposta a un INSERT e il trigger esegue un'altra istruzione INSERT).

  • SCOPE_IDENTITY(): restituisce l'ultimo valore di identità generato nell'ambito corrente (vale a dire stored procedure, trigger, funzione, ecc.).

  • IDENT_CURRENT(): restituisce l'ultimo valore di identità per una tabella specifica. Non utilizzare questo per ottenere il valore dell'identità da un INSERT, è soggetto a condizioni di competizione (cioè più connessioni che inseriscono righe sulla stessa tabella).

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

Per ulteriori di riferimento, vedi: http://msdn.microsoft.com/en-us/library/ms187342.aspx.

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

+0

+1 Ben riassunto – Kamal

+0

+1 per la spiegazione dettagliata. – Tebo

3

Scope Identity: Identità dell'ultimo record aggiunto all'interno della stored procedure in esecuzione.

@@Identity: identità dell'ultimo record aggiunto all'interno del batch di query o come risultato della query, ad es. 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.

6

Per chiarire il problema con @@Identity:

Per esempio, se si inserisce un tavolo e quel tavolo ha trigger facendo inserti, @@Identity tornerà l'id dall'inserto nel trigger (un log_id o qualcosa del genere), mentre scope_identity() restituirà l'ID dall'inserto nella tabella originale.

Quindi, se non si dispone di trigger, scope_identity() e @@identity restituirà lo stesso valore. Se hai trigger, devi pensare al valore che desideri.

10

Scope indica il contesto del codice che esegue la dichiarazione INSERTSCOPE_IDENTITY(), in contrasto con l'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 

Fornisce risultati diversi.

+0

Grazie per l'esempio. – Tebo

2

@@ identità è una variabile globale usata per ottenere l'ultimo ID generato a livello globale. Mentre scope_identity utilizzato per ottenere l'ultimo ID generato in un ambito (procedura o funzione). Per ulteriori dettagli vedere a: - @@Identity is a globa variable used for to get the last generated id globally. While scope_identity used for to get the last generated id in a scope(procedure or function). For more detail see at :- http://interview-preparation-for-you.blogspot.com/2011/02/identity-and-scope-identity.html

11

Se si capisce la differenza tra ambito e sessione, sarà molto facile comprendere questi metodi.

Un bel blog post da Adam Anderson descrive questa differenza:

sessione significa che la connessione corrente che sta eseguendo il comando.

L'ambito 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 tale comando genera qualsiasi trigger, ciascun trigger viene eseguito all'interno del proprio ambito nidificato.

Così le differenze tra i tre metodi di recupero di identità sono i seguenti:

@@identity restituisce l'ultimo valore Identity generato in questa sessione ma qualsiasi ambito.

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

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

6

A causa del bug citato da @David Freitas e a causa dell'incompatibilità con la nuova funzionalità Sequence introdotta nel 2012, consiglierei di stare lontano da tutti e tre questi. Invece, puoi usare la clausola OUTPUT per ottenere il valore di identità inserito. L'altro vantaggio è che OUTPUT funziona anche se hai inserito più di una riga.

Per dettagli ed esempi vedere qui: Identity Crisis

3

Ecco un altro buona spiegazione da the book:

Per quanto riguarda la differenza tra SCOPE_IDENTITY e @@ IDENTITY, si supponga di avere una P1 stored procedure con tre dichiarazioni:
- Un INSERT che genera un nuovo valore di identità
- Una chiamata a una procedura memorizzata P2 che ha anche un'istruzione INSERT che genera un nuovo valore di identità
- Una dichiarazione 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).