Come posso utilizzare la clausola OUTPUT di un'istruzione INSERT per ottenere il valore dell'identità?


240

Se ho un'istruzione insert come:

INSERT INTO MyTable
(  
  Name,
  Address,
  PhoneNo
)
VALUES
(
  'Yatrix',
   '1234 Address Stuff',
   '1112223333'
)

Come posso impostare @var INTil valore di identità della nuova riga (chiamato Id) usando la clausola OUTPUT? Ho visto esempi di come inserire INSERTED.Name in variabili di tabella, ad esempio, ma non riesco a inserirlo in una variabile non di tabella.

Ci ho provato OUPUT INSERTED.Id AS @var, SET @var = INSERTED.Idma nessuno dei due ha funzionato.


3
Conosco già @@ SCOPE_IDENTITY, in particolare voglio sapere come farlo con OUPUT. Grazie.
Yatrix,

6
È necessario inserirlo in una variabile di tabella, quindi selezionare da quello. Non esiste sintassi da assegnare direttamente a una variabile scalare dalla OUTPUTclausola.
Martin Smith,

3
La clausola OUTPUT deve essere emessa in una tabella o variabile di tabella.
mellamokb

5
La OUTPUTclausola scrive su una tabella. Può essere una tabella variabile, tabella temporanea, ....
HABO,

2
La mia domanda chiede specificamente la clausola OUTPUT.
Yatrix,

Risposte:


464

Puoi avere l'ID appena inserito in output sulla console SSMS in questo modo:

INSERT INTO MyTable(Name, Address, PhoneNo)
OUTPUT INSERTED.ID
VALUES ('Yatrix', '1234 Address Stuff', '1112223333')

Puoi usarlo anche ad es. Da C #, quando devi recuperare l'ID nella tua app chiamante - esegui la query SQL con .ExecuteScalar()(invece di .ExecuteNonQuery()) per leggere il risultato risultante ID.

Oppure, se è necessario acquisire il IDT-SQL appena inserito (ad es. Per successive elaborazioni successive), è necessario creare una variabile di tabella:

DECLARE @OutputTbl TABLE (ID INT)

INSERT INTO MyTable(Name, Address, PhoneNo)
OUTPUT INSERTED.ID INTO @OutputTbl(ID)
VALUES ('Yatrix', '1234 Address Stuff', '1112223333')

In questo modo, è possibile inserire più valori @OutputTble elaborarli ulteriormente. Puoi anche usare una tabella temporanea "normale" ( #temp) o persino una tabella persistente "reale" come "destinazione di output" qui.


2
La risposta qui per il codice dietro era concisa. ExecuteScalar () FTW
Joe Johnston,

10
È possibile inserire il risultato in un real persistent table- questo è estremamente fantastico perché significa che è possibile INSERTinformazioni contemporaneamente nelle TWOtabelle.
Gotqn

7
Non usare mai @@ IDENTITY per estrarre dall'alto. Scoperta nel modo più duro lavorando con i trigger e dal momento che stavano registrando la cronologia delle modifiche apportate a una tabella e inserendole in una nuova tabella contemporaneamente @@ IDENTITY ha iniziato a restituire i valori dalla tabella della cronologia. l'ilarità deriva da lì! Si prega di utilizzare la soluzione di marc_s. per ora sono andato con il metodo @OutputTbl, ma sono incuriosito dalle altre opzioni.
Eric Bishard,

4
OUTPUT INTO è estremamente fantastico, tranne per il fatto che "La tabella di destinazione della clausola OUTPUT INTO non può trovarsi su entrambi i lati di una relazione (chiave primaria, chiave esterna)", che per me rappresenta circa il 99% dei potenziali casi d'uso. Suppongo che ciò avvenga perché la clausola OUTPUT può restituire dati anche quando viene eseguito il rollback della transazione, ma è un po 'fastidioso che sia così difficile inserirli nei dati nelle relative tabelle A e B in un colpo solo.
Robert Calhoun,

3
@EricBishard SCOPE_IDENTITY()funziona meglio per questo.
Derreck Dean,
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.