2009-06-10 13 views
11

Sto inserendo in una tabella SQLServer con un campo chiave autoincremento. (Credo che questo è chiamato una colonna IDENTITY in SQLServer.)Come posso restituire un nuovo valore di colonna IDENTITY da un'istruzione SELECT SQLServer?

In Oracle, posso usare la parola chiave Tornando a dare la mia dichiarazione inserire un set di risultati come una query SELECT che restituirà il valore generato:

INSERT INTO table 
(foreign_key1, value) 
VALUES 
(9, 'text') 
RETURNING key_field INTO :var; 

Come ottengo ciò in SQLServer?

Bonus: Va bene, risposte belle finora, ma come faccio a mettere in una singola istruzione, se possibile? :)

+0

Aggiunto esempio "una chiamata". – gbn

risposta

17

In generale, non può essere eseguito in una singola istruzione.

Ma SELECT SCOPE_IDENTITY() può (e deve) essere posizionato direttamente dopo l'istruzione INSERT, quindi è tutto fatto nella stessa chiamata al database.

Esempio:

mydb.ExecuteSql("INSERT INTO table(foreign_key1, value) VALUES(9, 'text'); SELECT SCOPE_IDENTITY();"); 

È possibile utilizzare l'uscita, ma ha alcune limitazioni si dovrebbe essere a conoscenza di:

http://msdn.microsoft.com/en-us/library/ms177564.aspx

+4

Incredibile. Non avevo idea di poter combinare affermazioni del genere. Intelligente, non standard, orribile, utile ... tutti questi aggettivi vengono in mente. :) – skiphoppy

+1

Può essere eseguito in un'unica istruzione in SQL Server 2005 con OUTPUT – gbn

9
SELECT SCOPE_IDENTITY() 

Edit: Avere un gioco ...

Se solo la clausola OUTPUT supportato variabili locali.

In ogni caso, per ottenere un intervallo di ID, piuttosto che un Singleton

DECLARE @Mytable TABLE (keycol int IDENTITY (1, 1), valuecol varchar(50)) 

INSERT @Mytable (valuecol) 
OUTPUT Inserted.keycol 
SELECT 'harry' 
UNION ALL 
SELECT 'dick' 
UNION ALL 
SELECT 'tom' 

Edit 2: In una chiamata. Non ho mai avuto occasione di usare questo costrutto.

DECLARE @Mytable TABLE (keycol int IDENTITY (1, 1), valuecol varchar(50)) 

INSERT @Mytable (valuecol) 
OUTPUT Inserted.keycol 
VALUES('foobar') 
+0

Io secondo questo. SCOPE_IDENTITY() restituisce l'identità più recente nell'ambito della query più recente. Altri metodi @@ IDENTITY e IDENT_CURRENT() non sono limitati a un ambito specifico –

+0

hhmm un downvote anonimo per questa risposta ... – gbn

2

SCOPE_IDENTITY

4

Oltre a @@ IDENTITY, si dovrebbe anche prendere in considerazione SCOPE_IDENTITY() e IDENT_CURRENT(). Molto probabilmente vuoi SCOPE_IDENTITY(). @@ IDENTITY ha un problema in quanto potrebbe restituire un valore di identità creato in un trigger sulla tabella effettiva che stai cercando di tracciare.

Inoltre, si tratta di funzioni a valore singolo. Non so come funzioni la parola chiave Oracle RETURNING.

0

È possibile utilizzare OUTPUT INTO, che presenta gli ulteriori vantaggi di poter acquisire più identità inserite.

0

INSERT INTO table (foreign_key1, value) VALORI (9, 'testo'); SELECT @@ IDENTITY;

2

Dipende dal contesto di chiamata.

Se si sta chiamando questo codice dal client, è possibile utilizzare OUTPUT e quindi leggere il valore restituito.

DECLARE @t TABLE (ColID int IDENTITY, ColStr varchar(20)) 

INSERT INTO @t (ColStr) 
OUTPUT Inserted.ColID 
VALUES ('Hello World') 

Risultato:

 ColID 
----------- 
      1 

Se stai avvolgere questo in una stored procedure, utilizzando l'uscita è più lavoro. Lì, ti consigliamo di utilizzare SCOPE_IDENTITY(), ma non puoi farlo in una singola istruzione. Certo, puoi mettere più istruzioni su una singola riga con un ';' separatore, ma non è una singola affermazione.

DECLARE @idValue int 
DECLARE @t TABLE (ColID int IDENTITY, ColStr varchar(20)) 

INSERT INTO @t (ColStr) VALUES ('Hello World') 

SELECT @idValue = SCOPE_IDENTITY() 

Risultato: la variabile @idValue contiene il valore dell'identità. Utilizzare un parametro OUTPUT per restituire il valore.

Problemi correlati