2009-06-10 13 views
11

Estoy insertando en una tabla SQLServer con un campo de clave autoincrementing. (Creo que esto se llama una columna de identidad de SQL Server.)¿Cómo devuelvo un nuevo valor de columna IDENTIDAD de una instrucción SELEC SQLServer?

En Oracle, que puede utilizar la palabra clave que vuelven a dar mi instrucción INSERT un conjunto de resultados como una consulta SELECT que devolverá el valor generado:

INSERT INTO table 
(foreign_key1, value) 
VALUES 
(9, 'text') 
RETURNING key_field INTO :var; 

¿Cómo puedo lograr esto en SQLServer?

Bonificación: Bien, buenas respuestas hasta ahora, pero ¿cómo puedo ponerlas en una sola declaración, si es posible? :)

+0

Ejemplo agregado de "una llamada". – gbn

Respuesta

17

En general, no se puede hacer en una sola declaración.

Pero el SELECT SCOPE_IDENTITY() puede (y debe) colocarse directamente después de la instrucción INSERT, por lo que todo se hace en la misma llamada a la base de datos.

Ejemplo:

mydb.ExecuteSql("INSERT INTO table(foreign_key1, value) VALUES(9, 'text'); SELECT SCOPE_IDENTITY();"); 

puede utilizar la salida, pero tiene algunas limitaciones que debe tener en cuenta:

http://msdn.microsoft.com/en-us/library/ms177564.aspx

+4

Increíble. No tenía idea de poder combinar declaraciones como esa. Inteligente, no estándar, horrible, útil ... todos estos adjetivos vienen a la mente. :) – skiphoppy

+1

Se puede hacer en una declaración en SQL Server 2005 con la SALIDA – gbn

9
SELECT SCOPE_IDENTITY() 

Editar: Tener un juego ...

Si sólo la cláusula OUTPUT apoyaron las variables locales.

De todos modos, para obtener un intervalo de identificadores en lugar de un conjunto unitario

DECLARE @Mytable TABLE (keycol int IDENTITY (1, 1), valuecol varchar(50)) 

INSERT @Mytable (valuecol) 
OUTPUT Inserted.keycol 
SELECT 'harry' 
UNION ALL 
SELECT 'dick' 
UNION ALL 
SELECT 'tom' 

Edición 2: En una llamada. Nunca tuve ocasión de usar esta construcción.

DECLARE @Mytable TABLE (keycol int IDENTITY (1, 1), valuecol varchar(50)) 

INSERT @Mytable (valuecol) 
OUTPUT Inserted.keycol 
VALUES('foobar') 
+0

En segundo lugar esto. SCOPE_IDENTITY() devuelve la identidad más reciente dentro del alcance de su consulta más reciente. Otros métodos @@ IDENTITY e IDENT_CURRENT() no se limitan a un alcance específico –

+0

hhmm un voto negativo anónimo para esta respuesta ... – gbn

2

SCOPE_IDENTITY

4

Además de @@ identity, también se debe buscar en SCOPE_IDENTITY() y IDENT_CURRENT(). Lo más probable es que desee SCOPE_IDENTITY(). @@ IDENTITY tiene un problema porque puede devolver un valor de identidad creado en un desencadenante en la tabla real que está tratando de rastrear.

Además, estas son funciones de valor único. No sé cómo funciona la palabra clave Oracle RETURNING.

0

Puede usar OUTPUT INTO, que tiene los beneficios adicionales de poder capturar múltiples identidades insertadas.

0

INSERT INTO tabla (foreign_key1, valor) VALORES (9, 'texto'); SELECCIONE @@ IDENTIDAD;

2

Depende del contexto de su llamada.

Si llama desde el código del cliente, puede usar OUTPUT y luego leer el valor devuelto.

DECLARE @t TABLE (ColID int IDENTITY, ColStr varchar(20)) 

INSERT INTO @t (ColStr) 
OUTPUT Inserted.ColID 
VALUES ('Hello World') 

Resultado:

 ColID 
----------- 
      1 

Si va a envolver esto en un procedimiento almacenado, usando salida es más trabajo. Allí, querrá usar SCOPE_IDENTITY(), pero no puede hacerlo en una sola declaración. Claro, puedes poner varias declaraciones en una sola línea con un ';' separador, pero esa no es una sola declaración.

DECLARE @idValue int 
DECLARE @t TABLE (ColID int IDENTITY, ColStr varchar(20)) 

INSERT INTO @t (ColStr) VALUES ('Hello World') 

SELECT @idValue = SCOPE_IDENTITY() 

Resultado: @idValue variable contains identity value. Use un parámetro OUTPUT para devolver el valor.

Cuestiones relacionadas