Vous êtes sur la page 1sur 13

OUT PUT

Devuelve informacin de las filas afectadas por una instruccin INSERT, UPDATE, DELETE o MERGE, o expresiones basadas en esas filas. Estos resultados se pueden devolver a la aplicacin de procesamiento para que los utilice en mensajes de confirmacin, archivado y otros requisitos similares de una aplicacin. Los resultados tambin se pueden insertar en una tabla o variable de tabla. Adems, puede capturar los resultados de una clusula OUTPUT en una instruccin anidada INSERT, UPDATE, DELETE e insertar los resultados en una tabla de destino o vista. Se utiliza en: DELETE, INSERT, UPDATE o MERGE Sintaxis de OUTPUT <OUTPUT_CLAUSE> ::= { [ OUTPUT <dml_select_list> INTO { @table_variable | output_table } [ ( column_list ) ] ] [ OUTPUT <dml_select_list> ] } <dml_select_list> ::= { <column_name> | scalar_expression } [ [AS] column_alias_identifier ] [ ,...n ] <column_name> ::= { DELETED | INSERTED | from_table_name } . { * | column_name } | $action Argumentos @table_variable Especifica una variable table en la que se insertan las filas devueltas en lugar de devolverse al autor de la llamada. Debe declararse @table_variable antes de la instruccin INSERT, UPDATE, DELETE. Si no se especifica column_list, la variable table debe tener el mismo nmero de columnas que el conjunto de resultados OUTPUT. Las excepciones son las columnas de identidad y calculadas, que deben omitirse. Si se especifica column_list, las columnas omitidas deben aceptar valores NULL o tener valores predeterminados asignados. output_table Especifica una tabla en la que se insertan las filas devueltas en lugar de devolverse al autor de la llamada. output_table puede ser una tabla temporal. Si no se especifica column_list, la tabla debe tener el mismo nmero de columnas que el conjunto de resultados OUTPUT. Las excepciones son las columnas de identidad y calculadas. stas deben omitirse. Si se especifica column_list, las columnas omitidas deben aceptar valores NULL o tener valores predeterminados asignados. output_table no puede: o Tener definidos desencadenadores habilitados. o Participar en alguna de las partes de una restriccin FOREIGN KEY.

Tener restricciones CHECK o reglas habilitadas.

column_list Es una lista opcional de nombres de columna de la tabla de destino de la clusula INTO. Es equivalente a la lista de columnas permitida en la instruccin INSERT. scalar_expression Es cualquier combinacin de smbolos y operadores que se evala como un solo valor. No se permiten funciones de agregado en scalar_expression. Cualquier referencia a las columnas de la tabla que se va a modificar debe calificarse con el prefijo INSERTED o DELETED. column_alias_identifier Es un nombre alternativo que se utiliza para hacer referencia al nombre de columna. DELETED Es un prefijo de columna que especifica el valor eliminado en la operacin de actualizacin o eliminacin. Las columnas con prefijo DELETED reflejan el valor antes de que se complete la instruccin UPDATE, DELETE o MERGE. DELETED no se puede utilizar con la clusula OUTPUT en la instruccin INSERT. INSERTED Es un prefijo de columna que especifica el valor agregado en la operacin de insercin o actualizacin. Las columnas con prefijo INSERTED reflejan el valor despus de que se complete la instruccin UPDATE, INSERT o MERGE, pero antes de que se ejecuten los desencadenadores. INSERTED no se puede utilizar con la clusula OUTPUT en la instruccin DELETE. from_table_name Es un prefijo de columna que especifica una tabla incluida en la clusula FROM de una instruccin DELETE, UPDATE o MERGE que se utiliza para especificar las filas que se van a actualizar o eliminar. Si la tabla que se va a modificar se especifica tambin en la clusula FROM, cualquier referencia a las columnas de esa tabla deben calificarse con el prefijo INSERTED o DELETED. Especifica que todas las columnas afectadas por la accin de eliminacin, insercin o actualizacin se devuelvan en el orden en que se encuentran en la tabla. Por ejemplo, OUTPUT DELETED.* en la siguiente instruccin DELETE devuelve todas las columnas eliminadas de la tabla PEDIDOS:
DELETE dbo.customer OUTPUT DELETED.*;

column_name Es una referencia explcita a una columna. Cualquier referencia a la tabla que se va a modificar debe certificarse correctamente mediante el prefijo INSERTED o DELETED, segn corresponda; por ejemplo: INSERTED.column_name. $action Solo est disponible para la instruccin MERGE. Especifica una columna de tipo nvarchar(10) en la clusula OUTPUT de una instruccin MERGE que devuelve uno de estos tres valores por cada fila: 'INSERT', 'UPDATE' o 'DELETE', segn la accin realizada en dicha fila.

USE BANCO; GO DELETE TOP(1) dbo.Clientes WITH (READPAST) OUTPUT deleted.* WHERE SECTOR < 4; GO

Ciertas caractersticas de la clusula OUTPUT La clusula OUTPUT puede ser til para recuperar el valor de las columnas de identidad o calculadas despus de una operacin con INSERT o UPDATE. Cuando se incluye una columna calculada en <dml_select_list>, la columna correspondiente de la tabla de salida o variable de tabla no es una columna calculada. Los valores de la nueva columna son los que se calcularon en el momento en que se ejecut la instruccin. No se garantiza que coincidan el orden en que se aplican los cambios en la tabla y el orden en que se insertan las filas en la tabla de salida o variable de tabla. Si se modifican parmetros o variables como parte de una instruccin UPDATE, la clusula OUTPUT siempre devuelve el valor del parmetro o la variable tal como se encontraba antes de ejecutar la instruccin, en lugar de devolver el valor modificado. OUTPUT se puede utilizar con una instruccin UPDATE o DELETE en un cursor que utilice la sintaxis WHERE CURRENT OF. La clusula OUTPUT no se admite en las siguientes instrucciones: Instrucciones DML que hacen referencia a vistas locales con particiones, vistas distribuidas con particiones o tablas remotas. Instrucciones INSERT que contienen una instruccin EXECUTE. Los predicados de texto completo no estn permitidos en la clusula OUTPUT cuando el nivel de compatibilidad de la base de datos est establecido en 100. La clusula OUTPUT INTO no se puede utilizar para realizar inserciones en vistas o en una funcin de conjunto de filas. No se puede crear una funcin definida por el usuario si contiene una clusula OUTPUT INTO que tiene una tabla como destino. La clusula OUTPUT no puede contener las referencias siguientes: Subconsultas o funciones definidas por el usuario que obtienen acceso a datos de usuario o del sistema, o que se asume que obtienen dicho acceso. Se supone que las funciones definidas por el usuario realizan el acceso a los datos si no estn enlazadas a un esquema. Una columna de una vista o funcin insertada con valores de tabla si la columna se define mediante uno de los mtodos siguientes: o Una subconsulta. o Una funcin definida por el usuario que obtiene acceso a datos de usuario o del sistema, o que se asume que obtiene dicho acceso. o Una columna calculada que contiene una funcin definida por el usuario que obtiene acceso a datos de usuario o del sistema en su definicin.

Insertar datos devueltos de una clusula OUTPUT en una tabla Al capturar los resultados de una clusula OUTPUT en una instruccin INSERT, UPDATE, DELETE o MERGE anidada e insertarlos en una tabla de destino, tenga presente la informacin siguiente: Toda la operacin es atmica. Se ejecutarn la instruccin INSERT y la instruccin DML anidada que contiene la clusula OUTPUT, o bien se producir un error en toda la instruccin. Las restricciones siguientes se aplican al destino de la instruccin INSERT externa: El destino no puede ser una expresin de tabla comn, vista o tabla remota. El destino no puede tener una restriccin FOREIGN KEY, ni ser objeto de referencia por una restriccin FOREIGN KEY. No se pueden definir desencadenadores en el destino. El destino no puede participar en la replicacin de mezcla ni en las suscripciones actualizables para la replicacin transaccional.

Las restricciones siguientes se aplican a la instruccin DML anidada: El destino no puede ser una tabla remota ni una vista con particiones. El propio origen no puede contener una clusula <dml_table_source>. La clusula OUTPUT INTO no se admite en instrucciones INSERT que contengan una clusula <dml_table_source>. @@ROWCOUNT devuelve las filas insertadas nicamente por la instruccin INSERT externa. @@IDENTITY, SCOPE_IDENTITY e IDENT_CURRENT devuelven los valores de identidad generados solo por la instruccin DML anidada, y no los generados por la instruccin INSERT externa. Las notificaciones de consulta tratan la instruccin como una entidad nica, y el tipo de cualquier mensaje creado es el del DML anidado, aunque el cambio significativo provenga de la propia instruccin INSERT externa. En la clusula <dml_table_source>, las clusulas SELECT y WHERE no pueden incluir subconsultas, funciones de agregado, funciones de categora, predicados de texto completo, funciones definidas por el usuario que realicen accesos a datos, ni la funcin TEXTPTR.

Desencadenadores Las columnas devueltas de OUTPUT reflejan los datos tal como estaban despus de completarse la instruccin INSERT, UPDATE o DELETE, pero antes de ejecutarse los desencadenadores. En el caso de los desencadenadores INSTEAD OF, los resultados devueltos se generan como si la operacin de INSERT, UPDATE o DELETE se hubiese producido realmente, aunque no se produzcan modificaciones como resultado de la operacin del desencadenador. Si se utiliza una instruccin que incluye una clusula OUTPUT en el cuerpo de un desencadenador, deben utilizarse alias de tabla para hacer referencia a las tablas inserted y deleted del desencadenador con el fin de evitar la duplicacin de las referencias a columnas con las tablas INSERTED y DELETED asociadas a OUTPUT.

Si la clusula OUTPUT se especifica sin especificar tambin la palabra clave INTO, el destino de la operacin DML no puede tener definido ningn desencadenador habilitado para la accin DML dada. Por ejemplo, si se define la clusula OUTPUT en una instruccin UPDATE, la tabla de destino no puede tener desencadenadores UPDATE habilitados. Si se establece la opcin sp_configure de disallow results from triggers, una clusula OUTPUT sin una clusula INTO har que la instruccin genere un error cuando se invoque desde un desencadenador. Tipos de datos La clusula OUTPUT admite los tipos de datos de objetos grandes: nvarchar(max), varchar(max), varbinary(max), text, ntext, image y xml. Cuando se utiliza la clusula .WRITE en la instruccin UPDATE para modificar una columna de tipo nvarchar(max), varchar(max) o varbinary(max), se devuelven las imgenes anterior y posterior completas de los valores si se hace referencia a ellas. La funcin TEXTPTR( ) no puede aparecer como parte de una expresin en una columna de tipo text, ntext o image en la clusula OUTPUT. COLAS OUTPUT se puede utilizar en aplicaciones que utilizan tablas como colas, o para contener conjuntos de resultados intermedios. Dicho de otro modo, la aplicacin agrega o quita filas de la tabla constantemente. En el ejemplo siguiente se utiliza la clusula OUTPUT en una instruccin DELETE para devolver la fila eliminada a la aplicacin que realiza la llamada. Transact-SQL
USE BANCO; GO DELETE TOP(1) dbo.Clientes WITH (READPAST) OUTPUT deleted.* WHERE SECTOR < 4; GO

En este ejemplo, se quita una fila de una tabla utilizada como cola y se devuelven los valores eliminados a la aplicacin de procesamiento en una nica accin. Tambin se puede implementar otro tipo de semntica, como utilizar una tabla para implementar una pila. No obstante, SQL Server no garantiza el orden en que las instrucciones DML procesan y devuelven las filas por medio de la clusula OUTPUT. Es la aplicacin la que debe incluir una clusula WHERE que garantice la semntica deseada, o reconocer que, si hay varias filas aptas para la operacin DML, no se garantiza el orden. En el ejemplo siguiente se utiliza una subconsulta y se supone que la unicidad es una caracterstica de la columna DatabaseLogID para implementar la semntica de ordenacin deseada. Transact-SQL
USE BANCO; GO

CREATE TABLE dbo.bancos ( id INT, nombre VARCHAR(32) ) go INSERT INTO dbo.bancos VALUES (1, 'Banco Central') ,(2, 'Banco Bolivariano') ,(3, 'Banco de Guayaquil') ,(4, 'Produbanco'); GO DECLARE @Variable_tabla TABLE ( id INT, nombre VARCHAR(32) ); PRINT 'bancos antes de la eliminacion' SELECT * FROM dbo.bancos; DELETE FROM dbo.bancos OUTPUT DELETED.* INTO @Variable_tabla WHERE id = 4 OR id = 2; PRINT 'bancos despues de la eliminacion' SELECT * FROM bancos; PRINT '@Variable_tabla, despues de la eliminacion' SELECT * FROM @Variable_tabla; DROP TABLE dbo.bancos;
(4 filas afectadas) bancos antes de la eliminacion

(4 filas afectadas) (2 filas afectadas) bancos despues de la eliminacion

(2 filas afectadas) @Variable_tabla, despues de la eliminacion

(2 filas afectadas)

Permisos Se requieren permisos SELECT en las columnas recuperadas a travs de <dml_select_list> o utilizadas en <scalar_expression>. Se requieren permisos INSERT en las tablas especificadas en <output_table>. Ejemplos A.Utilizar OUTPUT INTO con una instruccin INSERT simple En el siguiente ejemplo se inserta una fila en la tabla ScrapReason y se utiliza la clusula OUTPUT para devolver los resultados de la instruccin a la variable table @Nuevo_Sector. Transact-SQL
USE banco; GO select * from Sector DECLARE @Nuevo_Sector table( codSector smallint,ubicacion varchar(50),nombreSector datetime); INSERT dbo.Sector OUTPUT INSERTED.codSector, INSERTED.ubicacion, INSERTED.nombreSector INTO @Nuevo_Sector VALUES (N'Operacion de error', GETDATE()); --Mostrar el resultado de Nuevo_Sector. SELECT * FROM @Nuevo_Sector; --Mostrar el resultado de Sector. SELECT * FROM Sector; GO

B.Usar OUTPUT con una instruccin DELETE En el ejemplo siguiente se eliminan todas las filas de la tabla Sector. La clusula OUTPUT deleted.* especifica que se devuelvan a la aplicacin que realiza la llamada los resultados de la instruccin DELETE, es decir, todas las columnas de las filas eliminadas. La instruccin SELECT posterior comprueba los resultados de la operacin de eliminacin en la tabla Sector. Transact-SQL
USE banco; select * from Sector GO

DELETE Sector OUTPUT DELETED.* WHERE codSector = 7; --Vericar la tabla despues de la eliminacion. SELECT COUNT(*) AS [Rows in Table] FROM Sector WHERE codSector = 7; GO

C.Usar OUTPUT INTO con una instruccin UPDATE Transact-SQL


DECLARE @Nuevo_Sector table( codSector int NOT NULL, ubicacion_anterior varChar(20), ubicacion_nueva varChar(20), nombreSector varChar(20)); UPDATE TOP (2) Sector SET ubicacion = 'SUR' OUTPUT inserted.codSector, deleted.ubicacion, inserted.ubicacion, inserted.nombreSector INTO @Nuevo_Sector; --Display the result set of the table variable. SELECT * FROM @Nuevo_Sector; GO --Display the result set of the table. SELECT TOP (2) * FROM Sector; GO

D.Usar OUTPUT INTO para devolver una expresin El ejemplo siguiente, se basa en el ejemplo C. Transact-SQL
use banco DECLARE @Nuevo_Sector table( codSector int NOT NULL, ubicacion_anterior varChar(20), ubicacion_nueva varChar(20), nombreSector_anterior varChar(20), nombreSector_nuevo varChar(20)); UPDATE TOP (2) Sector SET ubicacion = 'SUR', nombreSector = 'EL EJIDO' OUTPUT inserted.codSector, deleted.ubicacion, inserted.ubicacion, deleted.nombreSector, inserted.nombreSector INTO @Nuevo_Sector; --Display the result set of the table variable. SELECT * FROM @Nuevo_Sector; GO

--Display the result set of the table. SELECT TOP (2) * FROM Sector; GO

E.Usar OUTPUT INTO con from_table_name en una instruccin UPDATE Transact-SQL


USE banco; GO DECLARE @Tabla_prueba table ( sector_anterior int NOT NULL, sector_nuevo int NOT NULL, codSucursal int NOT NULL, nomSucursal nvarchar(50)NOT NULL, ubicacion nvarchar(50)NOT NULL); UPDATE Sucursal SET sector = 4 OUTPUT deleted.sector, inserted.sector, inserted.codSucursal, inserted.nomSucursal, Se.ubicacion INTO @Tabla_prueba FROM Sucursal AS Su INNER JOIN Sector AS Se ON Su.sector= Se.codSector AND Su.codSucursal= 1 SELECT * FROM @Tabla_prueba; GO

F.Usar OUTPUT INTO con from_table_name en una instruccin DELETE En el ejemplo siguiente se eliminan las filas de la tabla ClientexCta segn los criterios de bsqueda definidos en la clusula FROM de la instruccin DELETE. Transact-SQL
USE banco; GO DECLARE @Variable_tabla table ( codCliente int NOT NULL, nombre nvarchar(50)NOT NULL, cuenta int NOT NULL, activo int NOT NULL); DELETE ClientexCta OUTPUT DELETED.codCliente, C.nombre, DELETED.numCta, DELETED.activo INTO @Variable_tabla FROM ClientexCta AS cli_cta JOIN Clientes as C ON cli_cta.codCliente = C.codCliente WHERE C.nombre = 'Julio Jose';

--Display the results of the table variable. SELECT * FROM @Variable_tabla GO

G.Usar OUTPUT INTO con un tipo de datos de objetos grandes Transact-SQL


USE AdventureWorks; GO DECLARE @Variable_tabla table ( Summary_antes nvarchar(max), Summary_despues nvarchar(max)); UPDATE Production.Document SET DocumentSummary .WRITE (N'features',28,10) OUTPUT deleted.DocumentSummary, inserted.DocumentSummary INTO @Variable_tabla WHERE Title = N'Front Reflector Bracket Installation'; SELECT * FROM @Variable_tabla; GO

H.Usar OUTPUT en un desencadenador INSTEAD OF En el ejemplo siguiente se utiliza la clusula OUTPUT en un desencadenador para devolver los resultados de la operacin del desencadenador. Transact-SQL
use banco GO select * from Sector IF OBJECT_ID('Vista1','V') IS NOT NULL DROP VIEW Vista1; GO CREATE VIEW Vista1 AS (SELECT * FROM Sector); GO CREATE TRIGGER t_Vista1 ON Vista1 INSTEAD OF INSERT AS BEGIN --ScrapReasonID is not specified in the list of columns to be inserted --because it is an IDENTITY column. INSERT INTO Sector (ubicacion,nombreSector) OUTPUT INSERTED.ubicacion,INSERTED.nombreSector SELECT ubicacion,nombreSector FROM inserted; END GO INSERT Vista1 (ubicacion,nombreSector) VALUES ('SUR','LA CAROLINA'); GO

I.Usar OUTPUT INTO con columnas de identidad y calculadas En el ejemplo siguiente se crea la tabla bancos y, despus, se insertan en ella varias filas utilizando una instruccin INSERT con una instruccin SELECT para recuperar los datos de las tablas de origen. Transact-SQL
USE banco; GO select * from Cuentas select * from Clientes select * from Sector IF OBJECT_ID ('dbo.bancos','U') IS NOT NULL DROP TABLE dbo.bancos; GO CREATE TABLE dbo.bancos ( ID int IDENTITY (1,5)NOT NULL, nombre nvarchar(50) NOT NULL, ubicacion nvarchar(50) NOT NULL, sector nvarchar(50) NOT NULL, ); GO DECLARE @Variable_tabla table( nombre nvarchar(50) NOT NULL, ubicacion nvarchar(50) NOT NULL, sector nvarchar(50) NOT NULL ); INSERT INTO dbo.bancos (nombre,ubicacion,sector) OUTPUT INSERTED.nombre, INSERTED.ubicacion, INSERTED.sector INTO @Variable_tabla SELECT c.nombre, c.direccion, S.nombreSector FROM Clientes AS c INNER JOIN Sector AS S ON C.sector = S.codSector WHERE C.apellido LIKE 'Pa%' ORDER BY c.apellido; SELECT * FROM @Variable_tabla; GO SELECT * FROM dbo.bancos; GO

J.Usar OUTPUT y OUTPUT INTO en una sola instruccin En el ejemplo siguiente se eliminan las filas de la tabla ClientexCta segn los criterios de bsqueda definidos en la clusula FROM de la instruccin DELETE. La clusula OUTPUT INTO devuelve las columnas de la tabla que se elimina y columnas de la tabla Product a la variable table @Variante_tabla.

Transact-SQL
USE banco; --select * from Clientes --select * from ClientexCta GO DECLARE @Variable_tabla table ( ClienteID int NOT NULL, nombre nvarchar(50)NOT NULL, numCta int NOT NULL, activo int NOT NULL); DELETE ClientexCta OUTPUT C.codCliente, C.nombre, DELETED.numCta, DELETED.activo INTO @Variable_tabla OUTPUT C.nombre,DELETED.numCta, GETDATE() AS Fecha_eliminacion FROM Clientes AS C JOIN ClientexCta as Cta ON C.codCliente = Cta.codCliente WHERE numCta = 2; --Display the results of the table variable. SELECT * FROM @Variable_tabla; GO

K.Insertar los datos devueltos por una clusula OUTPUT El ejemplo siguiente captura datos devueltos por la clusula OUTPUT de una instruccin MERGE y los inserta en otra tabla. Transact-SQL
USE banco; GO IF OBJECT_ID(N'dbo.HistorialCuentas',N'U') IS NOT NULL DROP TABLE dbo.HistorialCuentas; GO --Create ZeroInventory table. CREATE TABLE dbo.HistorialCuentas (numCta_Eliminada int, Fecha_eliminacion DateTime); GO INSERT INTO dbo.HistorialCuentas (numCta_Eliminada,Fecha_eliminacion) SELECT numCta, GETDATE() FROM ( MERGE dbo.Cuentas AS C USING (SELECT numCta,saldo_Contable FROM Cuentas C2 where C2.titulo = 'B') as C1 (numCta,saldo_Contable) ON (C.numCta = C1.numCta)

WHEN MATCHED THEN UPDATE SET C.saldo_Contable = C.saldo_Contable + C1.saldo_Contable OUTPUT $action, deleted.numCta) AS Changes (Action,numCta) WHERE Action = 'UPDATE'; IF @@ROWCOUNT = 0 PRINT 'Ninguna fila fue actualizada'; GO SELECT * FROM dbo.HistorialCuentas;

Vous aimerez peut-être aussi