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.
Non c'è bisogno di un SELECT separato ...
INSERT INTO table (name)
OUTPUT Inserted.ID
VALUES('bob');
Funziona anche per colonne non IDENTITY (come GUID)
Utilizzare SCOPE_IDENTITY()
per ottenere il nuovo valore ID
INSERT INTO table (name) VALUES('bob');
SELECT SCOPE_IDENTITY()
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:
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.
@@ IDENTITY È una funzione di sistema che restituisce il valore dell'identità inserito per ultimo.
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
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
È 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.
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)