2012-02-16 82 views
21

con C# en Visual Studio, estoy insertar una fila en una tabla como la siguiente:Valor de retorno del comando de SQL Server Inserte usando C#

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

quiero hacer algo como esto, pero no lo hago conocer la sintaxis correcta:

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

Esto devolvería la columna de la foo_id de la fila recién insertada.

Además, incluso si encuentro la sintaxis correcta para esto, tengo otro problema: tengo SqlDataReader y SqlDataAdapter a mi disposición. Hasta donde yo sé, el primero es para leer datos, el segundo es para manipular datos. Al insertar una fila con una declaración de devolución, estoy manipulando y leyendo datos, así que no estoy seguro de qué usar. Tal vez hay algo completamente diferente que debería usar para esto?

Respuesta

62

SCOPE_IDENTITY devuelve el último valor de identidad insertado en una columna de identidad en el mismo ámbito. Un alcance es un módulo: un procedimiento almacenado, desencadenador, función o lote. Por lo tanto, dos instrucciones están en el mismo ámbito si están en el mismo procedimiento, función o lote almacenados.

Puede usar SqlCommand.ExecuteScalar para ejecutar el comando de inserción y recuperar la nueva ID en una consulta.

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

qué gran ejemplo Tim, me ayudó mucho. Gracias por publicar una pregunta como esta Neko, ¡exactamente lo que estaba buscando! – WhySoSerious

+0

me hizo un error de los caracteres encontrados después de la instrucción sql –

13

probar esto:

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

SALIDA puede devolver un conjunto de resultados (entre otras cosas), véase: OUTPUT Clause (Transact-SQL). Además, si inserta varios valores (INSERT SELECT), este método devolverá una fila por cada fila insertada, mientras que otros métodos solo devolverán información en la última fila.

ejemplo de trabajo:

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

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

SALIDA:

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

(1 row(s) affected) 
+0

Esto funciona. Nunca supe sobre OUTPUT hasta ahora. ¡Gracias! – lamarant

+0

Esto no funciona cuando hay Disparadores en la mesa. En ese caso, obtendrá el siguiente error: 'La tabla de destino de la declaración DML no puede tener activadores habilitados si la instrucción contiene una cláusula OUTPUT sin la cláusula INTO. Sin embargo, no estoy seguro de lo que significan con' sin la cláusula INTO, ya que La instrucción INSERT tiene una cláusula INTO ... –

+1

@Louis Somers, simplemente una cláusula 'OUTPUT' simple devolverá un conjunto de resultados. Si agrega un '' INTO'' se insertará en una tabla. Cree una variable de tabla: 'DECLARE @Temp table (xyz int, abc varchar (5))' y puede hacer que las filas 'OUTPUT' entren en esta tabla, luego, después de' INSERT' puede 'SELECT' the' @ Tabla Temp' para devolver un conjunto de resultados. Use algo como esto: 'OUTPUT INSERTED.col1, INSERTED.col2 INTO @ Temp' y después de 'INSERT' algo así como: '; SELECT * FROM @ Temp'. –

-1

Creo que puede usar @@ IDENTITY para esto, pero creo que hay algunas reglas/restricciones especiales al respecto?

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

[Realmente debería usar 'SCOPE_IDENTITY()' y ** NOT ** '@@ IDENTITY' - que podrían arrojar resultados sorprendentemente incorrectos!] (Http: // blog. sqlauthority.com/2007/03/25/sql-server-identity-vs-scope_identity-vs-ident_current-retrieve-last-inserted-identity-of-record /) –

Cuestiones relacionadas