M2 - Bases de dades / Exercicis UF3: Llenguatges SQL / Solucions PL-SQL T15
T15- Creació de triggers
- Exercici 1
Les operacions DML sobre taules només es permetran en hores de feina, es a dir, entre les 8:45 del matí i las 5:50 de la tarda; de dilluns a divendres.
a) crea un procediment emmagatzemat anomenat SECURE_DML que mostri un missatge d'error, en cas de no complir la regla anterior, com "Només es pot modificar dades en horari de feina".
- CREATE OR REPLACE PROCEDURE secure_dml
- IS
- BEGIN
- IF TO_CHAR (SYSDATE, 'HH24:MI') NOT BETWEEN '08:45' AND '17:30'
- OR TO_CHAR (SYSDATE, 'DY') IN ('SAT', 'SUN') THEN
- IF TO_CHAR (SYSDATE, 'HH24:MI') NOT BETWEEN '08:45' AND '17:30'
- RAISE_APPLICATION_ERROR (-20205, 'Només es permeten canvis en horari doficina.');
- END IF;
- END secure_dml;
- /
- Exercici 2
Crea un trigger en la taula PRODUCT que cridi al procediment anterior.
- CREATE OR REPLACE TRIGGER secure_prod
- BEFORE INSERT OR UPDATE OR DELETE ON product
- CREATE OR REPLACE TRIGGER secure_prod
- BEGIN
- secure_dml();
- END secure_prod;
a) prova el procediment modificant la franja horària proposada anteriorment e intentant afegir un nou registre en la taula PRODUCT. Després de la comprovació restableix els valors originals.
SQL> INSERT INTO product 2 VALUES (99999, 'El meu producte');
- Exercici 3
La comissió d'un venedor canviaria amb qualsevol comanda nova o canvis en les comandes existents. La seva comissió s'emmagatzema en la columna COMM de la taula EMP. En la taula CUSTOMER s'assigna un venedor a un client particular.
a) crea un procediment que actualitzarà la comissió del venedor. Utilitzaràs paràmetres per enviar l'identificador del client, el total antic de la comanda i el total nou de la comanda, des del trigger que es fa la crida. El procediment necessitarà localitzar el codi del empleat en la taula CUSTOMER i actualitzar el registre del venedor en la taula EMP, afegint una nova comissió al valor existent (percentatge de comissió el 5% del total de la comanda).
- CREATE OR REPLACE PROCEDURE update_comm
- (v_custid IN NUMBER,
- v_old_tot IN NUMBER,
- v_new_tot IN NUMBER)
- IS
- CREATE OR REPLACE PROCEDURE update_comm
- v_repid NUMBER;
- v_comm NUMBER;
- BEGIN
- SELECT repid
- INTO v_repid
- FROM customer
- WHERE custid = v_custid;
- v_comm := (NVL(v_new_tot, 0) - NVL(v_old_tot, 0)) * .05;
- UPDATE emp
- SET comm = comm + v_comm
- WHERE empno = v_repid;
- END update_comm;
- /
b) Crea un trigger en la taula ORD que cridi al procediment, passant els paràmetres necessaris.
- CREATE OR REPLACE TRIGGER update_emp_comm
- AFTER INSERT OR UPDATE OR DELETE ON ord
- FOR EACH ROW
- CREATE OR REPLACE TRIGGER update_emp_comm
- BEGIN
- update_comm (:new.custid, :old.total, :new.total);
- END;
- /
c) Modifica la comanda 601 per assignar-li un total de 3$. Comprova que la comissió de WARD s'ha incrementat en 0.03. La comissió original era de 500.
SQL> UPDATE ord 2 SET total = 3 3 WHERE ordid = 601;
SQL> SELECT ename, comm 2 FROM emp 3 WHERE ename = 'WARD'; ENAME COMM ------- --------- WARD 500.03
- Exercici 4
A las taules EMP i DEPT se'ls aplica una sèrie de regles de negoci.
Implementa les regles de negoci mitjançant triggers.
Reglas de negocio:
1. La taula EMP hauria de contenir exactament un PRESIDENT. Comproveu la resposta.
- CREATE OR REPLACE TRIGGER presidente
- BEFORE DELETE OR INSERT OR UPDATE OF JOB ON emp
- FOR EACH ROW
- CREATE OR REPLACE TRIGGER presidente
- BEGIN
- IF DELETING AND :OLD.JOB = 'PRESIDENT' THEN
- RAISE_APPLICATION_ERROR (-20001, 'No es pot eliminar al PRESIDENT');
- END IF;
- IF UPDATING THEN
- IF :OLD.JOB = 'PRESIDENT' THEN
- IF :NEW.JOB != 'PRESIDENT' THEN
- RAISE_APPLICATION_ERROR (-20002, 'EL PRESIDENT no pot deixar de ser-ho');
- END IF;
- ELSE
- IF :NEW.JOB = 'PRESIDENT' THEN
- RAISE_APPLICATION_ERROR (-20003, 'Ja tenim un PRESIDENT');
- END IF;
- END IF;
- END IF;
- IF INSERTING AND :NEW.JOB = 'PRESIDENT' THEN
- RAISE_APPLICATION_ERROR (-20003, 'Ja tenim un PRESIDENT');
- END IF;
- END presidente;
- /
SQL> INSERT INTO emp (empno, ename, job, deptno) 2 VALUES (7800,'HARRIS','PRESIDENT',20);
2. Els salaris només podran augmentar-se, no disminuir-se.
- CREATE OR REPLACE TRIGGER check_sal
- BEFORE UPDATE OF sal ON emp
- FOR EACH ROW
- WHEN (new.sal < old.sal)
- CREATE OR REPLACE TRIGGER check_sal
- BEGIN
- RAISE_APPLICATION_ERROR (-20004, 'Els salaris no es poden reduir');
- END check_sal;
- /
SQL> UPDATE emp 2 SET sal = 1100 3 WHERE empno = 7934;
3. Si un departament es trasllada a una altra ubicació, cada empleat d'aquest departament tindrà automàticament un increment de salari del 2%.
- CREATE OR REPLACE TRIGGER change_location
- AFTER UPDATE OF loc ON dept
- FOR EACH ROW
- WHEN (OLD.loc != NEW.loc)
- CREATE OR REPLACE TRIGGER change_location
- BEGIN
- UPDATE emp
- SET sal = sal * 1.02
- WHERE deptno = :NEW.deptno;
- END change_location;
- /
SQL> SELECT ename, sal, deptno 2 FROM emp 3 WHERE deptno = 30; ENAME SAL DETNO ------- --------- ---------- BLAKE 2850 30 MARTIN 1250 30 ALLEN 1600 30 ...
SQL> UPDATE dept 2 SET loc = 'HOUSTON' 3 WHERE deptno = 30; SQL> SELECT ename, sal, deptno 2 FROM emp 3 WHERE deptno = 30; ENAME SAL DETNO ------- --------- ---------- BLAKE 2907 30 MARTIN 1275 30 ALLEN 1632 30 ...