ultimo - SQL Server-Devolver valor después de INSERT
scope_identity (11)
@@ IDENTIDAD Es una función del sistema que devuelve el último valor de identidad insertado.
Estoy intentando recuperar el valor-clave después de una instrucción INSERT. Ejemplo: Tengo una tabla con los atributos nombre e id. ID es un valor generado.
INSERT INTO table (name) VALUES(''bob'');
Ahora quiero recuperar la identificación en el mismo paso. ¿Cómo se hace esto?
Estamos utilizando Microsoft SQL Server 2008.
Así es como uso OUTPUT INSERTED, cuando inserto en una tabla que usa ID como columna de identidad en 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)
Después de hacer una inserción en una tabla con una columna de identidad, puede hacer referencia a @@ IDENTITY para obtener el valor: http://msdn.microsoft.com/en-us/library/aa933167%28v=sql.80%29.aspx
Entity Framework realiza algo similar a la respuesta de 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
Los resultados de salida se almacenan en una variable de tabla temporal y, a continuación, se seleccionan de nuevo para el cliente. Hay que tener en cuenta el gotcha:
las inserciones pueden generar más de una fila, por lo que la variable puede contener más de una fila, por lo que se le puede devolver más de una
ID
No tengo idea de por qué EF uniría la mesa efímera con la tabla real (en qué circunstancias no coincidirían las dos).
Pero eso es lo que hace EF.
SQL Server 2008 o más reciente solamente. Si es el 2005, entonces estás fuera de suerte.
La mejor y más segura solución es usar SCOPE_IDENTITY. solo tiene que obtener la identidad del ámbito después de cada inserción y guardarlo en una variable porque puede llamar a dos inserciones en el mismo ámbito. @identity y @@ identity pueden funcionar, pero no son un ámbito seguro. Puedes tener problemas en una gran aplicación.
declare @duplicataId int
select @duplicataId = (SELECT SCOPE_IDENTITY())
Más detalles están aquí documentos de Microsoft
No es necesario un SELECT separado ...
INSERT INTO table (name)
OUTPUT Inserted.ID
VALUES(''bob'');
Esto también funciona para las columnas que no son de IDENTIDAD (como los GUID)
Puede agregar una declaración de selección a su declaración de inserción. Integer myInt = Insertar en la tabla1 (FName) valores (''Fred''); Seleccione Scope_Identity (); Esto devolverá un valor de la identidad cuando se ejecuta el escalador.
Puede usar scope_identity para seleccionar el ID de la fila que acaba de insertar en una variable y luego seleccionar las columnas que desee de esa tabla donde id = la identidad que obtuvo de scope_identity
Consulte aquí la información de MSDN http://msdn.microsoft.com/en-us/library/ms190315.aspx
Use SCOPE_IDENTITY()
para obtener el nuevo valor de ID
INSERT INTO table (name) VALUES(''bob'');
SELECT SCOPE_IDENTITY()
* El orden de los parámetros en la cadena de conexión a veces es importante. * La ubicación del parámetro Proveedor puede romper el cursor del conjunto de registros después de agregar una fila. Vimos este comportamiento con el proveedor SQLOLEDB.
Después de agregar una fila, los campos de la fila no están disponibles, A MENOS QUE el proveedor se especifique como el primer parámetro en la cadena de conexión. Cuando el proveedor se encuentra en cualquier lugar de la cadena de conexión, excepto como primer parámetro, los campos de fila recién insertados no están disponibles. Cuando movimos el proveedor al primer parámetro, los campos de la fila aparecieron mágicamente.
INSERT INTO files (title) VALUES (''whatever'');
SELECT * FROM files WHERE id = SCOPE_IDENTITY();
Es la apuesta más segura ya que existe un problema conocido con el conflicto de cláusula de SALIDA en las tablas con activadores. Hace que esto sea bastante poco confiable, incluso si su tabla no tiene actualmente ningún desencadenante: alguien que agregue uno en la línea romperá su aplicación. Bomba de tiempo tipo de comportamiento.
Vea el artículo de msdn para una explicación más profunda: