Beruflich Dokumente
Kultur Dokumente
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;
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 '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;
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
Deleted
idfab=fab
AND
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
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
-- 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;
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 ]
ON pedidos FOR INSERT AS UPDATE FROM empleados SET ventas=ventas+inserted.importe empleados, inserted inserted.importe IS NOT NULL;
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.
DISABLE TRIGGER
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;
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