Citation preview

TRIGGERS

1. Crear un trigger sobre la tabla empleados para que no se permita que un empleado sea jefe de más de cinco empleados. CREATE OR REPLACE TRIGGER JEFE_NO_5 BEFORE INSERT ON EMPLOYEES FOR EACH ROW DECLARE jefe_de NUMBER; BEGIN SELECT count(*) INTO jefe_de FROM EMPLOYEES WHERE manager_id = :NEW.manager_id; IF jefe_de > 5 THEN raise_application_error (-20800,:NEW.manager_id||' No se puede ser jefe de más de 5 empleados'); END IF; END; / insert into employees values (210, 'Ricardo', 'Herrera', 'RHERRERA','515.123.4568','21/09/89', 'AD_VP',17000,0,101,90,NULL);

2. Crear un trigger para impedir que se aumente el salario de un empleado en más de un 20%. Es necesario comparar los valores :old.salario y :new.salario cuando se modifica (BEFORE UPDATE). CREATE OR REPLACE TRIGGER AUMENTO_SALARIO BEFORE UPDATE OF salary ON employees FOR EACH ROW BEGIN IF :NEW.salary > :OLD.salary*1.20 THEN raise_application_error (-20800,:NEW.salary||' No se puede aumentar el salario en más del 20%'); END IF; END; / UPDATE EMPLOYEES SET salary=30000 WHERE employee_id=101;

3. Crear un trigger para impedir que un pertenezcan a departamentos distintos.

empleado

y

CREATE OR REPLACE TRIGGER DEPARTAMENTOS_DISTINTOS BEFORE INSERT ON EMPLOYEES FOR EACH ROW DECLARE emp_dep EMPLOYEES.DEPARTMENT_ID%TYPE; man_dep EMPLOYEES.DEPARTMENT_ID%TYPE; BEGIN SELECT department_id INTO man_dep FROM employees employee_id=:NEW.manager_id;

su

jefe

WHERE

IF :NEW.department_id man_dep THEN raise_application_error (-20800,:NEW.employee_id||' Un empleado no puede trabajar en un departamento diferente al de su jefe'); END IF; END; / insert into employees values (210, 'Ricardo', 'Herrera', 'RHERRERA','515.123.4568','21/09/89', 'AD_VP',17000,0,101,80,NULL);

4. Una librería almacena los datos de sus libros en una tabla denominada "libros" y controla las actualizaciones del precio de los libros almacenando en la tabla "control" el nombre del usuario, la fecha, el precio anterior y el nuevo. Creamos las tablas con las siguientes estructuras: create table libros( codigo number(6), titulo varchar2(40), autor varchar2(30), editorial varchar2(20), precio number(6,2) ); create table control( usuario varchar2(30), fecha date, codigo number(6), precioanterior number(6,2), precionuevo number(6,2) ); Ingresamos algunos registros en "libros": insert into libros values(100,'Uno','Richard Bach','Planeta',25); insert into libros values(103,'El aleph','Borges','Emece',28); insert into libros values(105,'Matematica estas ahi','Paenza','Nuevo siglo',12); insert into libros values(120,'Aprenda PHP','Molina Mario','Nuevo siglo',55); insert into libros values(145,'Alicia en el pais de las maravillas','Carroll','Planeta',35);

1. Crear un trigger llamado "tr_actualizar_precio_libros" a nivel de fila que se dispara "antes" que se ejecute un "update" sobre el campo "precio" de la tabla "libros". En el cuerpo del disparador se debe ingresar en la tabla "control", el nombre del usuario que realizó la actualización, la fecha, el código del libro que ha sido modificado, el precio anterior y el nuevo. CREATE OR REPLACE TRIGGER tr_actualizar_precio_libros BEFORE UPDATE OF precio ON libros FOR EACH ROW BEGIN INSERT INTO control VALUES(USER,SYSDATE,:NEW.codigo,:OLD.precio,:NEW.precio); END tr_actualizar_precio_libros; UPDATE libros SET precio=40 WHERE codigo=100; select * from control;

2. Reemplazar el trigger anteriormente creado. Ahora el disparador "tr_actualizar_precio_libros" debe controlar el precio que se está actualizando, si supera los 50 pesos, se debe redondear tal valor a entero hacia abajo (empleando la función "floor", sino lo tiene créela), es decir, se modifica el valor ingresado accediendo a ":new.precio" asignándole otro valor. CREATE OR REPLACE TRIGGER tr_actualizar_precio_libros BEFORE UPDATE OF precio ON libros FOR EACH ROW BEGIN IF (:new.precio>50) THEN :new.precio:=floor(:new.precio); END IF; INSERT INTO control VALUES(USER,SYSDATE,:NEW.codigo,:OLD.precio,:NEW.precio); END tr_actualizar_precio_libros; UPDATE libros set precio=53 WHERE codigo=100; SELECT * FROM control;

3. Creamos un disparador para múltiples eventos, que se dispare al ejecutar "insert", "update" y "delete" sobre "libros". En el cuerpo del trigger se realiza la siguiente acción: se almacena el nombre del usuario, la fecha y los antiguos y viejos valores de "precio": CREATE OR REPLACE TRIGGER tr_libros BEFORE INSERT OR UPDATE OR DELETE ON libros FOR EACH ROW BEGIN INSERT INTO control VALUES(USER,SYSDATE,:OLD.codigo,:OLD.precio,:NEW.precio); END tr_libros; INSERT INTO libros VALUES(101,'La vuelta al mundo en 80 días','Julio Verne','Planeta',80); UPDATE libros SET precio=88 WHERE codigo=101; SELECT * FROM control;