2011-05-06 9 views
22

Tengo una consulta INSERT y deseo que el DB devuelva el ID de la fila que acabo de insertar.Devuelva la identificación en INSERTAR?

sqlString = "INSERT INTO MagicBoxes (OwnerID, Key, Name, Permissions, Active, LastUpdated) VALUES (@OwnerID, @BoxKey, @BoxName, 0, 1, @Date) SET @ID = SCOPE_IDENTITY();"; 
cmd = new SqlCommand(sqlString, con); 
cmd.Parameters.AddWithValue("@OwnerID", OwnerID); 
cmd.Parameters.AddWithValue("@BoxKey", BoxKey); 
cmd.Parameters.AddWithValue("@BoxName", BoxName); 
cmd.Parameters.AddWithValue("@Username", Username); 
cmd.Parameters.AddWithValue("@Date", DateTime.Now); 
cmd.ExecuteNonQuery(); 

Actualmente tengo esto, no estoy seguro de lo que tengo que hacer a continuación ...

+0

No se puede obtener a su pregunta, ¿desea el valor de inicialización de la fila acaba de insertar? –

Respuesta

31

sólo tiene que añadir a la colección @ID params y luego recuperarlo como este,

cmd.Parameters.Add("@ID", SqlDbType.Int, 4).Direction = ParameterDirection.Output; 
cmd.ExecuteNonQuery(); 
//Now just read the value of: cmd.Parameters["@ID"].value 

O, si se prefiere esta sintaxis:

SqlParameter param = new SqlParameter("@ID", SqlDbType.Int, 4); 
param.Direction = ParameterDirection.Output; 
cmd.Parameters.Add(param); 
+0

'Argumento 4: no se puede convertir de 'System.Data.ParameterDirection' a 'string'' – Danpe

+0

@Danpe = disculpas, corregido arriba - Siempre encuentro que los parámetros de salida añadidos son un poco más torpes de lo que necesita ser – AdaTheDev

+2

No puedo hacer este trabajo, después de ejecutar el comando el parámetro es nulo. Otra respuesta aquí usa ExecuteScalar y parece producir el valor correcto. –

20

usted tiene dos opciones; puede declarar un parámetro Output llamado @ID; o - se puede cambiar el final de SELECT SCOPE_IDENTITY() y sólo tiene que utilizar:

int id = (int)cmd.ExecuteScalar(); 

Yo prefiero el enfoque de parámetros formales, pero ExecuteScalar funciona bien.

3

Agregar a su parámetros

SqlParameter IDParameter = new SqlParameter("@ID",SqlDbType.Int); 
IDParameter.Direction = ParameterDirection.Output; 
cmd.Parameters.Add(IDParameter); 

Después de ejecutar puede recuperar el ID

int id = (int)IDParameter.Value; 
0

¿Por qué no llamas a la hora de almacenarlo. Pase los valores al procedimiento de almacenamiento para obtener los valores insertados y desde el SP devuelva el último valor inicial insertado usando SCOPE_IDENTITY(). Espero que esta ayuda.

+0

teniendo un procedimiento almacenado no cambiaría nada; esto es sobre el argumento/resultado que pasa, que sería idéntico –

+0

Sí, tienes razón, quise decir que llama SP y que SP devuelva el último valor inicial después de la inserción. –

12

Desde SQL Server 2008 hubo un OUTPUT clause agregado a la sintaxis de TSQL. Esto le permite tener los datos que se ven afectados por la consulta DML agregada al flujo de datos tabulares.

Aunque consultar SCOPE_IDENTITY() después de que una consulta devuelve la información correcta, obliga a SQL Server a ejecutar 2 consultas donde la cláusula de salida limita esto a una consulta.

Sabiendo esto, la consulta que se está ejecutando se pueden modificar de la siguiente manera (suponiendo [Id] es el nombre de la identidad):

INSERT INTO MagicBoxes (OwnerID, [Key], Name, [Permissions], Active, LastUpdated) 
OUTPUT INSERTED.Id 
VALUES (@OwnerID, @BoxKey, @BoxName, 0, 1, @Date) 

Otro problema no se deshaga de la SqlCommand. La mayoría de los objetos Sql... en ADO.net implementan IDisposable y deben eliminarse de manera adecuada.

Llevar todo junto me gustaría poner en práctica este pedazo de código como sigue:

 using (var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["db"].ConnectionString)) 
     using (var cmd = new SqlCommand(@" 
       INSERT INTO MagicBoxes (OwnerID, [Key], Name, [Permissions], Active, LastUpdated) 
       OUTPUT INSERTED.Id 
       VALUES (@OwnerID, @BoxKey, @BoxName, 0, 1, @Date) ", conn)) 
     { 
      cmd.Parameters.AddRange(new[] 
       { 
        new SqlParameter("@OwnerID", SqlDbType.Int).Value = OwnerID, 
        new SqlParameter("@BoxKey", SqlDbType.VarChar).Value = BoxKey, 
        new SqlParameter("@BoxName", SqlDbType.VarChar).Value = BoxName, 
        new SqlParameter("@Date", SqlDbType.DateTime).Value = DateTime.Now 
       }); 

      conn.Open(); 

      var id = (int)cmd.ExecuteScalar(); 
     } 
+1

Esta es la mejor respuesta. –

Cuestiones relacionadas