it-swarm.it

SQL Server: restituisce il valore dopo INSERT

Sto cercando di ottenere un valore-chiave dopo un'istruzione INSERT. Esempio: Ho una tabella con gli attributi nome e id. id è un valore generato.

    INSERT INTO table (name) VALUES('bob');

Ora voglio riportare l'ID nello stesso passo. Come è fatto?

Stiamo utilizzando Microsoft SQL Server 2008.

242
melbic

Non c'è bisogno di un SELECT separato ...

INSERT INTO table (name)
OUTPUT Inserted.ID
VALUES('bob');

Funziona anche per colonne non IDENTITY (come GUID)

389
gbn

Utilizzare SCOPE_IDENTITY() per ottenere il nuovo valore ID

INSERT INTO table (name) VALUES('bob');

SELECT SCOPE_IDENTITY()

http://msdn.Microsoft.com/en-us/library/ms190315.aspx

152
Curt
INSERT INTO files (title) VALUES ('whatever'); 
SELECT * FROM files WHERE id = SCOPE_IDENTITY();

È la scommessa più sicura poiché esiste un problema noto con il conflitto delle clausole OUTPUT sulle tabelle con trigger. Rende questo abbastanza inaffidabile, anche se la tua tabella non ha al momento alcun trigger: qualcuno che ne aggiunge uno alla fine interromperà la tua applicazione. Tipo di comportamento Time Bomb.

Vedi l'articolo di msdn per una spiegazione più approfondita:

http://blogs.msdn.com/b/sqlprogrammability/archive/2008/07/11/update-with-output-clause-triggers-and-sqlmoreresults.aspx

33
hajikelist

Entity Framework esegue qualcosa di simile alla risposta di gbn:

DECLARE @generated_keys table([Id] uniqueidentifier)

INSERT INTO Customers(FirstName)
OUTPUT inserted.CustomerID INTO @generated_keys
VALUES('bob');

SELECT t.[CustomerID]
FROM @generated_keys AS g 
   JOIN dbo.Customers AS t 
   ON g.Id = t.CustomerID
WHERE @@ROWCOUNT > 0

I risultati di output sono memorizzati in una variabile di tabella temporanea e quindi selezionati nuovamente nel client. Bisogna essere consapevoli del gotcha:

gli inserti possono generare più di una riga, quindi la variabile può contenere più di una riga, quindi puoi essere restituito più di uno ID

Non ho idea del motivo per cui EF si unirebbe interiormente al tavolo effimero al tavolo reale (in quali circostanze i due non corrisponderebbero).

Ma questo è ciò che EF fa. 

Solo SQL Server 2008 o versioni successive. Se è il 2005, allora sei sfortunato.

20
Ian Boyd

@@ IDENTITY È una funzione di sistema che restituisce il valore dell'identità inserito per ultimo.

8
AngelaG

Puoi usare scope_identity per selezionare l'ID della riga che hai appena inserito in una variabile, quindi seleziona solo le colonne che vuoi da quella tabella dove id = l'identità che hai ottenuto da scope_identity

Vedi qui per le informazioni su MSDN http://msdn.Microsoft.com/en-us/library/ms190315.aspx

4
Purplegoldfish

la soluzione migliore e più sicura sta usando SCOPE_IDENTITY . Devi solo ottenere l'identità dell'oscilloscopio dopo ogni inserto e salvarlo in una variabile perché puoi chiamare due inserti nello stesso scope @ identity e @@ identity possono essere che lavorano ma non sono un ambito sicuro. puoi avere problemi in una grande applicazione

  declare @duplicataId int
  select @duplicataId =   (SELECT SCOPE_IDENTITY())

Maggiori dettagli sono qui Microsoft docs

2
MNF

È possibile aggiungere un'istruzione select alla propria istruzione insert Integer myInt = Inserisci nei valori table1 (FName) ('Fred'); Seleziona Scope_Identity (); Ciò restituirà un valore dell'identità quando viene eseguito lo scaler.

0
Robert Quinn

Questo è il modo in cui utilizzo OUTPUT INSERTED, quando si inserisce in una tabella che utilizza l'ID come colonna Identity in SQL Server:

'myConn is the ADO connection, RS a recordset and ID an integer
Set RS=myConn.Execute("INSERT INTO M2_VOTELIST(PRODUCER_ID,TITLE,TIMEU) OUTPUT INSERTED.ID VALUES ('Gator','Test',GETDATE())")
ID=RS(0)
0
Richard Zembron