Cláusula de salida de SQL Server en una variable escalar


134

¿Hay alguna forma "simple" de hacer esto o necesito pasar por una variable de tabla con la sintaxis "OUTPUT ... INTO"?

DECLARE @someInt int

INSERT INTO MyTable2(AIntColumn)
OUTPUT @SomeInt = Inserted.AIntColumn
VALUES(12)

Respuestas:


161

Necesita una variable de tabla y puede ser así de simple.

declare @ID table (ID int)

insert into MyTable2(ID)
output inserted.ID into @ID
values (1)

45
Pero luego tendría que "SELECCIONAR @someInt = ID DE @ID". Quería saber si es posible omitir ese paso adicional (y la variable de tabla intermedia) si todo lo que necesito es el int resultante.
Benoittr

@Benoittr: eso depende de cómo vaya a usar el valor, puede que no sea necesario, puede usar la tabla en una cláusula from de una instrucción select Cuando asigna una variable, también debe asegurarse de que la inserción solo inserte una fila. Y si el inserto solo inserta una fila, ¿tal vez es más fácil obtener lo que se usa en la cláusula de valores directamente en lugar de usar output?
Mikael Eriksson

44
En el caso del valor generado automáticamente, no siempre es posible conocer los valores con anticipación (identidad, columnas calculadas). Entiendo que hay muchas soluciones. Aún así, me diste la respuesta que estaba buscando. Gracias
Benoittr

¿Lo necesita en una variable regular? DECLARE @InsertedIDResults TABLE (ID int); INSERT INTO MyTable (Name, Age) OUTPUT INSERTED.ID INTO @InsertedIDResults VALUES('My Name', 30); DECLARE @InsertedID int = (SELECT TOP 1 ID FROM @InsertedIDResults);
Arvo Bowen

30

Más de un año después ... si lo que necesita es obtener el ID generado automáticamente de una tabla, puede simplemente

SELECT @ReportOptionId = SCOPE_IDENTITY()

De lo contrario, parece que estás atascado con el uso de una tabla.


66
La variable que estaba buscando realmente era algo más que la columna de identidad. Aún así, gracias por la respuesta.
Benoittr

26
Aparentemente, esto tiene problemas en un plan paralelo de múltiples procesadores, y OUTPUT es el único método siempre confiable.
andrewb

66
SCOPE_IDENTITY () podría devolver algo incluso si el último INSERT no insertó nada, ¿verdad? Eso lo haría inutilizable en algunos casos.
Patrick Honorez

2
mejor cláusula de salida
Clay Smith

1
El error al que se refiere @andrewb se solucionó en 2008 R2 SP1 .
adam0101

6

Mucho más tarde, pero aún vale la pena mencionar, es que también puede usar variables para generar valores en la cláusula SET de una ACTUALIZACIÓN o en los campos de un SELECCIONAR;

DECLARE @val1 int;
DECLARE @val2 int;
UPDATE [dbo].[PortalCounters_TEST]
SET @val1 = NextNum, @val2 = NextNum = NextNum + 1
WHERE [Condition] = 'unique value'
SELECT @val1, @val2

En el ejemplo anterior, @ val1 tiene el valor anterior y @ val2 tiene el valor posterior, aunque sospecho que cualquier cambio de un disparador no estaría en val2, por lo que tendría que ir con la tabla de salida en ese caso. Para todo menos el caso más simple, creo que la tabla de salida también será más legible en su código.

Un lugar en el que esto es muy útil es si desea convertir una columna en una lista separada por comas;

DECLARE @list varchar(max) = '';
DECLARE @comma varchar(2) = '';
SELECT @list = @list + @comma + County, @comma = ', ' FROM County
print @list

¡Gracias! Esta fue la información que necesitaba
Wizou

1
¡GUAUU! No sabía que puedes hacer SET @val2 = NextNum = NextNum + 1.
Sam
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.