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)
Benoittr
fuente

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)
Mikael Eriksson
fuente
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.

Alejandro B.
fuente
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
Jay13
fuente
¡Gracias! Esta fue la información que necesitaba
Wizou
1
¡GUAUU! No sabía que puedes hacer SET @val2 = NextNum = NextNum + 1.
Sam