2012-02-16 18 views
21

con C# in Visual Studio, sto inserendo una riga in una tabella come questa:Valore restituito dal comando SQL Server Inserire utilizzando C#

INSERT INTO foo (column_name) 
VALUES ('bar') 

voglio fare qualcosa di simile, ma non lo faccio conoscere la sintassi corretta:

INSERT INTO foo (column_name) 
VALUES ('bar') 
RETURNING foo_id 

Ciò riportare la colonna foo_id dalla nuova riga inserita.

Inoltre, anche se trovo la sintassi corretta per questo, ho un altro problema: ho SqlDataReader e SqlDataAdapter a mia disposizione. Per quanto ne so, il primo è per la lettura dei dati, il secondo è per la manipolazione dei dati. Quando inserisco una riga con un'istruzione return, sto manipolando e leggendo i dati, quindi non sono sicuro di cosa usare. Forse c'è qualcosa di completamente diverso che dovrei usare per questo?

risposta

62

SCOPE_IDENTITY restituisce l'ultimo valore di identità inserito in una colonna Identity nello stesso ambito. Un ambito è un modulo: una stored procedure, trigger, funzione o batch. Pertanto, due istruzioni sono nello stesso ambito se si trovano nella stessa stored procedure, funzione o batch.

È possibile utilizzare SqlCommand.ExecuteScalar per eseguire il comando di inserimento e recuperare il nuovo ID in una query.

using (var con = new SqlConnection(ConnectionString)) { 
    int newID; 
    var cmd = "INSERT INTO foo (column_name)VALUES (@Value);SELECT CAST(scope_identity() AS int)"; 
    using (var insertCommand = new SqlCommand(cmd, con)) { 
     insertCommand.Parameters.AddWithValue("@Value", "bar"); 
     con.Open(); 
     newID = (int)insertCommand.ExecuteScalar(); 
    } 
} 
+0

che bel esempio, Tim, mi ha aiutato molto. Grazie per aver postato una domanda come questa Neko, esattamente quello che stavo cercando! – WhySoSerious

+0

mi ha fatto un errore caratteri trovati dopo la fine della dichiarazione sql –

13

provare questo:

INSERT INTO foo (column_name) 
OUTPUT INSERTED.column_name,column_name,... 
VALUES ('bar') 

USCITA può restituire un set di risultati (tra le altre cose), vedi: OUTPUT Clause (Transact-SQL). Inoltre, se inserisci più valori (INSERT SELECT) questo metodo restituirà una riga per riga inserita, dove altri metodi restituiranno solo informazioni sull'ultima riga.

esempio funzionante:

declare @YourTable table (YourID int identity(1,1), YourCol1 varchar(5)) 

INSERT INTO @YourTable (YourCol1) 
OUTPUT INSERTED.YourID 
VALUES ('Bar') 

OUTPUT:

YourID 
----------- 
1 

(1 row(s) affected) 
+0

Questo funziona. Non ho mai saputo di OUTPUT fino ad ora. Grazie! – lamarant

+0

Questo non funziona quando ci sono trigger sul tavolo. In questo caso verrà visualizzato il seguente errore: 'La tabella di destinazione dell'istruzione DML non può avere trigger attivati ​​se l'istruzione contiene una clausola OUTPUT senza clausola INTO. Non sono sicuro che cosa intendano con' senza clausola INTO' L'istruzione INSERT ha una clausola INTO ... –

+1

@Louis Somers, solo una semplice clausola 'OUTPUT' restituirà un set di risultati. Se aggiungi un '' INTO'', questo verrà inserito in una tabella. Crea una variabile di tabella: 'DECLARE @Temp table (xyz int, abc varchar (5))' e puoi avere le righe di 'OUTPUT' in questa tabella, quindi dopo' INSERT' puoi semplicemente 'SELECT' the' @ Tabella Temp' per restituire un set di risultati. Usa qualcosa di simile a questo: 'OUTPUT INSERTED.col1, INSERTED.col2 INTO @ Temp', quindi dopo 'INSERT' qualcosa come:'; SELECT * FROM @ Temp'. –

-1

Penso che tu possa usare @@ IDENTITY per questo, ma penso che ci siano alcune regole/restrizioni speciali intorno ad esso?

using (var con = new SqlConnection("connection string")) 
{ 
    con.Open(); 
    string query = "INSERT INTO table (column) VALUES (@value)"; 

    var command = new SqlCommand(query, con); 
    command.Parameters.Add("@value", value); 
    command.ExecuteNonQuery(); 

    command.Parameters.Clear(); 
    command.CommandText = "SELECT @@IDENTITY"; 

    int identity = Convert.ToInt32(command.ExecuteScalar()); 
} 
+4

[Dovresti usare davvero 'SCOPE_IDENTITY()' e ** NOT ** '@@ IDENTITY' - che potrebbe restituire risultati sorprendentemente sbagliati!] (Http: // blog. sqlauthority.com/2007/03/25/sql-server-identity-vs-SCOPE_IDENTITY-vs-IDENT_CURRENT-recuperare-last-inserito-identità di record /) –

Problemi correlati