2008-12-01 45 views

Respuesta

73
INSERT INTO YourTable(val1, val2, val3 ...) 
VALUES(@val1, @val2, @val3...); 
SELECT SCOPE_IDENTITY(); 

No olvide el punto y coma al final de cada instrucción.

+3

en lugar de usar scope_identity(), solo podría usar la cláusula de salida - INSERT INTO YourTable (val1, val2, val3 ...) salida insertada. $ Identity VALUES (@ val1, @ val2, @ val3 ...); –

+8

No, no puedes. Si su tabla tiene desencadenantes, obtendrá este error: La tabla de destino 'Sitio' de la declaración DML no puede tener activadores habilitados si la instrucción contiene una cláusula OUTPUT sin la cláusula INTO. – pilavdzice

16
insert into Yourtable() 
values() 
SELECT SCOPE_IDENTITY() 

que acaba de ejecutar una prueba y verifica que los puntos y comas son opcionales utilizando SQL Server 2005 SP2, y .Net 3.5

+0

No sé nada sobre el downvote, pero SET NOCOUNT ON no es necesario para que esto funcione. Podría ser el punto y coma que falta. –

+0

en ADO 6.0 el conjunto no se requeriría si se retira un conjunto de registros, por lo tanto, podría ser ;-). Acabo de ejecutar una prueba y no necesita los puntos y coma y no necesita establecer nocount – JoshBerke

1

directamente de la Whirlpool:

If you're using MS SQL you can use "SELECT @@IDENTITY as Value" after your insert to get the last ID generated

y:

@@IDENTITY and SCOPE_IDENTITY return the last identity value generated in any table in the current session. However, SCOPE_IDENTITY returns the value only within the current scope; @@IDENTITY is not limited to a specific scope.

Editar: Como ou puntas t en los comentarios, siempre debe usar SCOPE_IDENTITY, no @@IDENTITY.

+1

Si tiene algún activador @@ Identity puede devolver el valor incorrecto – JoshBerke

+1

Siempre use SCOPE_IDENTITY. No @@ Identidad. –

23

Añada la siguiente línea al final de la consulta SQL ...

SELECT SCOPE_IDENTITY() 

y luego usar el método ExecuteScalar en el objeto SqlCommand ...

var rowCount = command.ExecuteScalar() 
2

Inmediatamente después de su inserción stmt , use

SELECT CAST(scope_identity() AS bigint) ---- incase you have a return result as int64 

Esto devolverá la columna creada id/identity.

2

No use @@ IDENTITY, por simple que parezca. Puede devolver valores incorrectos.

SELECT SCOPE_IDENTITY() 

parece ser la elección obvia.

5

Agregue un parámetro de salida al objeto de comando y luego establezca el valor en la nueva ID en el procedimiento almacenado.

procedimiento almacenado:

@ID AS INT OUTPUT 

[Insert Command] 

SET @ID = SCOPE_IDENTITY() 

.NET:

cmd.CommandText = "stored_procedure"; 

SqlParameter pID = new SqlParameter("ID", DBType.Int32, 4); 

pID.Direction = ParameterDirection.Output; 

cmd.ExecuteScalar(); 

int id = Convert.ToInt32(cmd.Parameters["ID"].Value.ToString()); 
1

Aunque me gusta Dave Markle's respuesta, (y veo que tú también, ya que marcó como su respuesta) , ese método puede fallar si tiene activadores en su base de datos, que auditan las operaciones de CUD y su tabla de auditoría tiene una columna de IDENTIDAD. Devolvería el valor de la identidad de la tabla de auditoría, no la tabla en la que acaba de insertar, ya que la tabla de auditoría se realizó después.

En ese caso, se puede usar un método más genérico que funcionará en ambos casos, independientemente de cualquier auditoría. Es un poco más prolijo, pero obtienes lo que pagas.

ejemplo:

@"DECLARE @tmp AS TABLE (id int) 
        INSERT INTO case 
        (
         caseID, 
         partID, 
         serialNumber, 
         hardware, 
         software, 
         firmware 
        ) 
        OUTPUT Inserted.ID into @tmp 
        VALUES 
        (
         @caseID, 
         @partItemID, 
         @serialNumber, 
         @hardware, 
         @software, 
         @firmware 
        ) 
       Select ID from @tmp") 
+2

Scope_identity no fallará si tiene desencadenantes, será @@ identity el que fallará. – HLGEM

+0

@Russ Su respuesta me ayudó cuando se trata de un error causado por desencadenantes de SyncFramework: 'La tabla de destino' dbo.table 'de la instrucción DML no puede tener activadores habilitados si la instrucción contiene una cláusula OUTPUT sin cláusula INTO'. Estoy usando un GUID para mi PK y no tengo una columna de IDENTIDAD. ¡Gracias! –

1

Si su id es un GUID, entonces me encontré con esta solución para ser mejor:

INSERT INTO YourTable (val1, val2, val3) 
OUTPUT inserted.id 
VALUES (@val1, @val2, @val3) 

Gracias @ Scott Ivey

demostración completa:

internal static Guid InsertNote(Note note) 
    { 
      Guid id; 

      using (
       var connection = 
        new SqlConnection(ConfigurationManager.ConnectionStrings["dbconn"].ConnectionString)) 
      { 
       connection.Open(); 
       using (
        var command = 
         new SqlCommand(
          "INSERT INTO Notes ([Title],[Text]) " + 
          "OUTPUT inserted.id " + 
          $"VALUES ('{title}','{text}');", connection)) 
       { 
        command.CommandType = CommandType.Text; 
        var reader = command.ExecuteReader(); 
        reader.Read(); 
        id = reader.GetGuid(reader.GetOrdinal("id")); 
       } 
       connection.Close(); 
      } 

      return id; 
    } 

I would r recomendar un procedimiento almacenado, pero esto es para pruebas unitarias de nuestro repositorio.

+0

¡Sí! Finalmente, después de buscar durante casi una hora, aparece una respuesta que muestra cómo obtener el valor de SALIDA en C# para un GUID. – Paul

Cuestiones relacionadas