Sie sind auf Seite 1von 9

Ejercicio paso a paso

Queremos que se guarde en una tabla EmpleadosInsertados el historial de inserciones de registros realizadas en la tabla empleados, adems de los datos del empleado se deber guardar en la tabla el usuario que realiz la insercin del empleado y la fecha/hora de la operacin. La primera vez el procedimiento deber crear la tabla y rellenarla con los empleados que ya existen. Para hacerlo aplicaremos el trigger en el FOR INSERT. PRINT 'Empieza el USE Gestion10 IF OBJECT_ID('HistorialEmpleados','TR') HistorialEmpleados GO CREATE TRIGGER ON Empleados FOR AS BEGIN IF OBJECT_ID('EmpleadosInsertados','U') IS NULL -- Si la tabla no creamos SELECT *,SUSER_SNAME()AS Usuario,GETDATE() AS FechaInsercion como es un SELECT ...INTO necesitamos usar alias de columna. INTO EmpleadosInsertados FROM Empleados; ELSE INSERT INTO insertamos las nuevas filas EmpleadosInsertados -Si la tabla ya existe -existe la HistorialEmpleados INSERT -- se ejecutar despus de insertar en Empleados IS NOT NULL DROP TRIGGER ejercicio de Triggers utilizando FOR INSERT'

SELECT *,SUSER_SNAME() AS Usuario,GETDATE()AS FechaInsercion FROM END; GO USE Gestion10 BEGIN TRY empleados INSERT Nuevo',0,10000); --Para probar el INTO Empleados Triger insertamos un empleado que no est ya en (numemp,nombre,ventas,cuota) -- Comprobamos que VALUES (218,'El Inserted;

SELECT * FROM EmpleadosInsertados; END TRY BEGIN CATCH

el nuevo empleado est

SELECT 'error', ERROR_MESSAGE()AS Mensaje END CATCH GO

Queremos que no se puedan eliminar fsicamente los pedidos, en vez de eliminarlo, se marcar como baja. Para ello debemos aadir a la tabla de pedidos un campo baja que contendr un cero o un uno, no podr contener ningn otro valor. En un principio est a cero y cuando se intente borrar el pedido, en vez de borrar el pedido se marcar este campo a 1. Para hacerlo aplicaremos el trigger en el INSTEAD OF DELETE. PRINT 'Empieza el USE Gestion10 ALTER TABLE GO UPDATE Empleados SET Baja=0 -- Para actualizar las filas que ya estn en Empleados Empleados ADD Baja BIT DEFAULT 0; -- Para crear la columna ejercicio de Triggers utilizando INSTED OF DELETE'

USE Gestion10 IF OBJECT_ID('Eliminarempleados','TR') IS NOT NULL DROP TRIGGER Eliminarempleados GO CREATE TRIGGER Eliminarempleados ON Empleados INSTEAD OF DELETE -- El trigger se pondr en marcha INSTEAD OF (En vez de) el DELETE que lanz el usuario. AS BEGIN UPDATE Empleados SET baja=1 FROM Empleados INNER JOIN Deleted ON empleados.numemp=Deleted.numemp END; GO USE Gestion10 BEGIN TRY -- Comprobamos cmo funciona SELECT 'Antes',* FROM Empleados ; -- Comprobamos los empleados que hay DELETE Empleados WHERE numemp=210; -- Un empleado que existe SELECT 'Despus DELETE',* FROM Empleados; -- comprobamos que el 210 sigue en la tabla con el campo Baja a 1 DELETE Empleados WHERE numemp=220; -- Un empleado que no existe SELECT 'Despus DELETE',* FROM Empleados; END TRY BEGIN CATCH SELECT 'error', ERROR_MESSAGE()AS Mensaje END CATCH GO Una variante del ejercicio anterior sera eliminar fsicamente el registro de la tabla empleados pero guardar una copia del registro eliminado en una tabla Empleados eliminados, guardando tambin en esa tabla la fecha de la eliminacin. Para hacerlo aplicaremos el trigger en el FOR DELETE. PRINT 'Empieza el ejercicio de Triggers utilizando FOR DELETE' USE Gestion10 -- Como vamos a definir un nuevo trigger para la misma operacin y sobre la misma tabla, primero eliminamos el primer trigger si existe. IF OBJECT_ID('Eliminarempleados','TR') IS NOT NULL DROP TRIGGER Eliminarempleados IF OBJECT_ID('Eliminarempleados2','TR') IS NOT NULL DROP TRIGGER Eliminarempleados2 GO CREATE TRIGGER Eliminarempleados2

ON Empleados FOR DELETE -- Ahora dejamos que se eliminen los registros y el trigger entrar en funcionamiento despus AS

BEGIN IF OBJECT_ID('EmpleadosEliminados','U') IS NULL SELECT *,SUSER_SNAME()AS Usuario,GETDATE() AS FechaInsercion como es un SELECT ...INTO es necesario utilizar alias. INTO EmpleadosEliminados FROM Empleados; ELSE INSERT INTO EmpleadosEliminados --

SELECT *,SUSER_SNAME() AS Usuario,GETDATE()AS FechaInsercion FROM END; GO USE Gestion10 BEGIN TRY -- Comprobamos cmo funciona el trigger Deleted;

SELECT 'Antes',* FROM Empleados WHERE numemp=210; DELETE Empleados WHERE numemp=210; -- Un empleado que existe y no es padre DELETE',* FROM Empleados WHERE numemp=210;

SELECT 'Empleados Despus SELECT 'EmpleadosEliminados DELETE Empleados WHERE

Despus DELETE',* FROM EmpleadosEliminados;

numemp=220; -- Un empleado que no existe Despus DELETE',* FROM EmpleadosEliminados;

SELECT 'EmpleadosEliminados

DELETE Empleados WHERE numemp=108; -- Un empleado que existe y es padre (salta un error de integridad referencial) SELECT 'Empleados Despus SELECT 'EmpleadosEliminados END TRY BEGIN CATCH PRINT 'Un error: ' + END CATCH GO Hacer que se actualicen automticamente las existencias de los productos cuando se inserte un nuevo pedido o cuando se rectifique la cantidad de uno existente. Se supone que un pedido produce una reduccin del stock (existencias) del producto. Para hacerlo aplicaremos el trigger en el FOR INSERT, UPDATE, y DELETE. PRINT 'Empieza el USE Gestion10 IF OBJECT_ID('ActualizaStock','TR') IS NOT NULL DROP TRIGGER ActualizaStock GO CREATE TRIGGER ActualizaStock ejercicio de Triggers utilizando FOR INSERT, UPDATE, DELETE' ERROR_MESSAGE() DELETE',* FROM Empleados WHERE numemp=108; numemp=108;

Despus DELETE',* FROM Empleados WHERE

ON Pedidos FOR INSERT,UPDATE,DELETE -- Definimos el trigger para operaciones, luego actuaremos segn la operacin que lo ha desencadenado. AS BEGIN UPDATE Productos SET existencias=existencias + Productos INNER JOIN Deleted.cant ON

todas

las

FROM idproducto=producto producto

Deleted

idfab=fab

AND

-- Sumamos la cantidad de los pedidos UPDATE Productos SET

que se han borrado al stock del

existencias=existencias - Inserted.cant

FROM Productos INNER JOIN Inserted ON idfab=fab AND idproducto=producto -- Restamos la cantidad de los del producto. -- Cuando la operacin sea un se inserta el nuevo, UPDATE primero se elimina el que haba y pedidos que se han insertado al stock

-- luego tendremos una fila en deleted y una fila en inserted y el stock finalmente quedar correcto. END; GO USE Gestion10 BEGIN TRY -- Lo probamos:

SELECT 'Antes',* FROM productos WHERE idfab='bic' AND idproducto=41003; -Para comprobar las existencias del producto INSERT INTO Pedidos (numpedido,fechapedido,rep,fab,producto,clie,cant,importe) VALUES (010101113,GETDATE(),108,'bic',41003,2103,10,1000); -- Insertamos un pedido de 10 unidades del producto en SELECT 'Despus idproducto=41003; INSERT',* FROM productos cuestion. WHERE idfab='bic' AND

-- Comprobamos que el campo UPDATE Pedidos SET

existencia se ha reducido en 10 unidades numpedido=010101113; producto,

cant= 5 WHERE

/* Ahora modificamos la cantidad en un pedido del mismo el pedido antes tena 10 y ahora 5 unidades, como se ha reducido en 5 cantidad.*/ SELECT 'Despus idproducto=41003; UPDATE',* FROM productos

unidades el stock debe de aumentar en esa WHERE idfab='bic' AND

-- Comprobamos que el campo DELETE Pedidos WHERE

existencias ha subido 5 unidades

numpedido=010101113; aunmentar 5 unidades WHERE idfab='bic' AND

-- Eliminamos el pedido, con lo que el stock debe de SELECT 'Despus idproducto=41003; DELETE',* FROM productos

-- Comprobamos que es as

END TRY BEGIN CATCH SELECT 'error', ERROR_MESSAGE()AS Mensaje END CATCH GO

http://www.lawebdelprogramador.com/foros/SQL/1221953-Trigger_+_AFTER_UPDATE.html#i1222109

Cuando se INSERTe un pedido, entrar en funcionamiento el trigger ActualizaVentasEmpleado y se ejecutarn las instrucciones que aparecen despus de AS, en este caso actualizar (UPDATE) la tabla empleados sumar a las ventas del empleado (ventas) el importe del pedido insertado (inserted.importe), y slo actualizar el empleado cuyo numemp coincida con el campo rep del pedido insertado (WHERE numemp=inserted.rep).
-- Ahora comprobamos que funciona SELECT * FROM empleados WHERE numemp=108;

INSERT INTO pedidos (numpedido,fechapedido,rep,clie,cant,importe,fab,producto) VALUES (123456789,getdate(),108,2103,10,100,'Aci',41001) numemp=108;

SELECT * FROM empleados WHERE

Vemos que al insertar un pedido de 100 del empleado 108, sus ventas han aumentado en 100. ALTER TRIGGER Permite modificar la definicin del desencadenador, no permite cambiar su nombre, para cambiar el nombre de un desencadenador hay que eliminarlo (DROP TRIGGER) y volver a crearlo (CREATE TRIGGER).
ALTER TRIGGER [NombreEsquema.]NombreTrigger ON {tabla|vista} {FOR|AFTER|INSTEAD OF} {[INSERT][,][UPDATE][,][DELETE]} [WITH APPEND] AS sentencia_sql [;] [,...n ]

La sintaxis es similar a la instruccin CREATE TRIGGER. Ejemplo:


ALTER TRIGGER ActualizaVentasEmpleados

ON pedidos FOR INSERT AS UPDATE FROM empleados SET ventas=ventas+inserted.importe empleados, inserted inserted.importe IS NOT NULL;

WHERE numemp=inserted.rep AND

Hemos modificado el desencadenador para que si el importe del pedido es nulo, no haga nada, no actualice con un valor nulo. Realiza el siguiente Ejercicio Triggers para practicar la creacin de desencadenadores.

9.13. DISABLE TRIGGER


En ocasiones puede ser til inhabilitar temporalmente un desencadenador sin que por ello suponga eliminarlo, para estos casos podemos utilizar la sentencia DISABLE TRIGGER.

DISABLE TRIGGER

{[NombreEsquema.]NombreTrigger [,...n] | ALL } ALL SERVER} [;]

ON {NombreTablaVista | DATABASE |

Ejemplo:
DISABLE TRIGGER ActualizaVentasEmpleado ON pedidos;

Deshabilita el desencadenador que hemos creado anteriormente, si despus de ejecutar esta sentencia se introduce un nuevo pedido, el empleado correspondiente no se actualizar. Lo podemos comprobar con:
SELECT * FROM empleados WHERE INSERT INTO pedidos numemp=108;

(numpedido,fechapedido,rep,clie,cant,importe,fab,producto) VALUES (123456791,getdate(),108,2103,10,300,'Aci',41001) numemp=108;

SELECT * FROM empleados WHERE DISABLE TRIGGER ALL ON pedidos;

Deshabilita todos los desencadenadores asociados a la tabla pedidos.


DISABLE TRIGGER ALL ON DATABASE;

Deshabilita todos los desencadenadores definidos en la base de datos actual.


DISABLE TRIGGER ALL ON ALL SERVER;

Deshabilita todos los desencadenadores definidos en el servidor.


Pg. 9.9

CREATE TRIGGER UpdateLinhasDoc ON LinhasDoc AFTER UPDATE AS DECLARE @IdCabecDoc Uniqueidentifier DECLARE @NumLinha SMALLINT DECLARE @PrecUnit FLOAT DECLARE @Quantidade SMALLINT DECLARE @QuantidadeDel SMALLINT DECLARE @QuantidadeOrig SMALLINT DECLARE @Status CHAR(3) SET NOCOUNT ON IF UPDATE(PrecUnit) or UPDATE(Quantidade) BEGIN SELECT @PrecUnit = PrecUnit, @Quantidade = Quantidade, @IdCabecDoc = IdCabecDoc, @NumLinha = NumLinha FROM inserted SELECT @QuantidadeDel = Quantidade FROM deleted IF EXISTS (SELECT * FROM MiddleLinhasDoc m JOIN inserted i ON m.IdCabecDoc = i.IdCabecDoc and m.NumLinha = i.NumLinha) BEGIN SELECT @Status = m.StatusLinha, @QuantidadeOrig = m.Quantidade FROM MiddleLinhasDoc m JOIN inserted i ON m.IdCabecDoc = i.IdCabecDoc and m.NumLinha = i.NumLinha IF (@Status LIKE 'INS') BEGIN UPDATE MiddleLinhasDoc SET PrecUnit = @PrecUnit, Quantidade = @Quantidade WHERE IdCabecDoc = @IdCabecDoc and NumLinha = @NumLinha END IF (@Status LIKE 'UPD') BEGIN BEGIN UPDATE MiddleLinhasDoc SET PrecUnit = @PrecUnit, Quantidade = (@Quantidade - @QuantidadeDel) + @QuantidadeOrig WHERE IdCabecDoc = @IdCabecDoc and NumLinha = @NumLinha END

END END ELSE BEGIN SELECT @PrecUnit = PrecUnit, @Quantidade = Quantidade, @IdCabecDoc = IdCabecDoc, @NumLinha = NumLinha FROM inserted INSERT INTO MiddleLinhasDoc(IdCabecDoc, NumLinha, PrecUnit, Quantidade, StatusLinha) VALUES (@IdCabecDoc, @NumLinha, @PrecUnit, @Quantidade - @QuantidadeDel, 'UPD') END END

Das könnte Ihnen auch gefallen