Sei sulla pagina 1di 22

C

Estudios para Implementacin


de Disparadores

Copyright 2004, Oracle. Todos los Derechos Reservados.

Objetivos
Al finalizar esta leccin, debera estar capacitado para lo
siguiente:
Mejorar la seguridad de la base de datos con
disparadores
Auditar los cambios de datos con disparadores DML
Forzar la integridad de los datos con disparadores DML
Mantener la integridad referencial con disparadores
Utilizar disparadores para replicar datos entre tablas
Utilizar disparadores para automatizar el clculo de
datos derivados
Proporcionar funciones de registro de eventos con
disparadores

Copyright 2004, Oracle. Todos los Derechos Reservados.

Control de la Seguridad en el Servidor


Uso de la Seguridad de la Base de Datos con la
Sentencia GRANT
GRANT SELECT, INSERT, UPDATE, DELETE
ON
employees
TO
clerk;
-- database role
GRANT clerk TO scott;

Copyright 2004, Oracle. Todos los Derechos Reservados.

Control de la Seguridad con un


Disparador de Base de Datos
CREATE OR REPLACE TRIGGER secure_emp
BEFORE INSERT OR UPDATE OR DELETE ON employees
DECLARE
dummy PLS_INTEGER;
BEGIN
IF (TO_CHAR (SYSDATE, 'DY') IN ('SAT','SUN')) THEN
RAISE_APPLICATION_ERROR(-20506,'You may only
change data during normal business hours.');
END IF;
SELECT COUNT(*) INTO dummy FROM holiday
WHERE holiday_date = TRUNC (SYSDATE);
IF dummy > 0 THEN
RAISE_APPLICATION_ERROR(-20507,
'You may not change data on a holiday.');
END IF;
END;
/
Copyright 2004, Oracle. Todos los Derechos Reservados.

Uso de la Utilidad del Servidor


para Auditora de Operaciones de Datos
El servidor de Oracle almacena la informacin de
auditora en una tabla de diccionario de datos o un
archivo del sistema operativo.
AUDIT INSERT, UPDATE, DELETE
ON departments
BY ACCESS
WHENEVER SUCCESSFUL;
Audit succeeded.

Copyright 2004, Oracle. Todos los Derechos Reservados.

Auditora con un Disparador


CREATE OR REPLACE TRIGGER audit_emp_values
AFTER DELETE OR INSERT OR UPDATE
ON employees FOR EACH ROW
BEGIN
IF (audit_emp_pkg. reason IS NULL) THEN
RAISE_APPLICATION_ERROR (-20059, 'Specify a
reason for operation through the procedure
AUDIT_EMP_PKG.SET_REASON to proceed.');
ELSE
INSERT INTO audit_emp_table (user_name,
timestamp, id, old_last_name, new_last_name,
old_salary, new_salary, comments)
VALUES (USER, SYSDATE, :OLD.employee_id,
:OLD.last_name, :NEW.last_name,:OLD.salary,
:NEW.salary, audit_emp_pkg.reason);
END IF;
END;
CREATE OR REPLACE TRIGGER cleanup_audit_emp
AFTER INSERT OR UPDATE OR DELETE ON employees
BEGIN audit_emp_package.g_reason := NULL;
END;
Copyright 2004, Oracle. Todos los Derechos Reservados.

Auditora de Disparadores con


Construcciones de Paquetes
DML en la tabla
EMPLOYEES
3
AUDIT_EMP_PKG
con variables
del paquete

AUDIT_EMPDML_TRG
AFTER STATEMENT
llama al procedimiento
AUDIT_EMP
AUDIT_TABLE

2
AUDIT_EMP_TRG
FOR EACH ROW
incrementa las
variables del
paquete

4
El procedimiento AUDIT_EMP
lee las variables del paquete,
actualiza AUDIT_TABLE y
restablece las variables del paquete

Copyright 2004, Oracle. Todos los Derechos Reservados.

Auditora de Disparadores con


Construcciones de Paquetes
Disparador de sentencia AFTER:
CREATE OR REPLACE TRIGGER audit_empdml_trg
AFTER UPDATE OR INSERT OR DELETE on employees
BEGIN
audit_emp;
-- write the audit data
END audit_emp_tab;
/

Disparador de fila AFTER:


CREATE OR REPLACE TRIGGER audit_emp_trg
AFTER UPDATE OR INSERT OR DELETE ON EMPLOYEES
FOR EACH ROW
-- Call Audit package to maintain counts
CALL audit_emp_pkg.set(INSERTING,UPDATING,DELETING);
/

Copyright 2004, Oracle. Todos los Derechos Reservados.

Paquete AUDIT_PKG
CREATE OR REPLACE PACKAGE audit_emp_pkg IS
delcnt PLS_INTEGER := 0;
inscnt PLS_INTEGER := 0;
updcnt PLS_INTEGER := 0;
PROCEDURE init;
PROCEDURE set(i BOOLEAN,u BOOLEAN,d BOOLEAN);
END audit_emp_pkg;
/
CREATE OR REPLACE PACKAGE BODY audit_emp_pkg IS
PROCEDURE init IS
BEGIN
inscnt := 0; updcnt := 0; delcnt := 0;
END;
PROCEDURE set(i BOOLEAN,u BOOLEAN,d BOOLEAN) IS
BEGIN
IF i THEN inscnt := inscnt + 1;
ELSIF d THEN delcnt := delcnt + 1;
ELSE upd := updcnt + 1;
END IF;
END;
END audit_emp_pkg;
/
Copyright 2004, Oracle. Todos los Derechos Reservados.

Tabla AUDIT_TABLE y
Procedimiento AUDIT_EMP
CREATE TABLE audit_table (
USER_NAME
VARCHAR2(30),
TABLE_NAME VARCHAR2(30),
INS
NUMBER,
UPD
NUMBER,
DEL
NUMBER)
/
CREATE OR REPLACE PROCEDURE audit_emp IS
BEGIN
IF delcnt + inscnt + updcnt <> 0 THEN
UPDATE audit_table
SET del = del + audit_emp_pkg.delcnt,
ins = ins + audit_emp_pkg.inscnt,
upd = upd + audit_emp_pkg.updcnt
WHERE user_name = USER
AND
table_name = 'EMPLOYEES';
audit_emp_pkg.init;
END IF;
END audit_emp;
/
Copyright 2004, Oracle. Todos los Derechos Reservados.

Forzado de Integridad de Datos


en el Servidor
ALTER TABLE employees ADD
CONSTRAINT ck_salary CHECK (salary >= 500);
Table altered.

Copyright 2004, Oracle. Todos los Derechos Reservados.

Proteccin de la Integridad de los Datos


con un Disparador
CREATE OR REPLACE TRIGGER check_salary
BEFORE UPDATE OF salary ON employees
FOR EACH ROW
WHEN (NEW.salary < OLD.salary)
BEGIN
RAISE_APPLICATION_ERROR (-20508,
'Do not decrease salary.');
END;
/

Copyright 2004, Oracle. Todos los Derechos Reservados.

Forzado de la Integridad Referencial


en el Servidor
ALTER TABLE employees
ADD CONSTRAINT emp_deptno_fk
FOREIGN KEY (department_id)
REFERENCES departments(department_id)
ON DELETE CASCADE;

Copyright 2004, Oracle. Todos los Derechos Reservados.

Proteccin de la Integridad Referencial


con un Disparador
CREATE OR REPLACE TRIGGER cascade_updates
AFTER UPDATE OF department_id ON departments
FOR EACH ROW
BEGIN
UPDATE employees
SET employees.department_id=:NEW.department_id
WHERE employees.department_id=:OLD.department_id;
UPDATE job_history
SET department_id=:NEW.department_id
WHERE department_id=:OLD.department_id;
END;
/

Copyright 2004, Oracle. Todos los Derechos Reservados.

Replicacin de Tablas en el Servidor

CREATE MATERIALIZED VIEW emp_copy


NEXT sysdate + 7
AS SELECT * FROM employees@ny;

Copyright 2004, Oracle. Todos los Derechos Reservados.

Replicacin de Tablas con un Disparador


CREATE OR REPLACE TRIGGER emp_replica
BEFORE INSERT OR UPDATE ON employees FOR EACH ROW
BEGIN /* Proceed if user initiates data operation,
NOT through the cascading trigger.*/
IF INSERTING THEN
IF :NEW.flag IS NULL THEN
INSERT INTO employees@sf
VALUES(:new.employee_id,...,'B');
:NEW.flag := 'A';
END IF;
ELSE
/* Updating. */
IF :NEW.flag = :OLD.flag THEN
UPDATE employees@sf
SET ename=:NEW.last_name,...,flag=:NEW.flag
WHERE employee_id = :NEW.employee_id;
END IF;
IF :OLD.flag = 'A' THEN :NEW.flag := 'B';
ELSE :NEW.flag := 'A';
END IF;
END IF;
END;
Copyright 2004, Oracle. Todos los Derechos Reservados.

Clculo de Datos Derivados en el Servidor

UPDATE departments
SET total_sal=(SELECT SUM(salary)
FROM employees
WHERE employees.department_id =
departments.department_id);

Copyright 2004, Oracle. Todos los Derechos Reservados.

Clculo de Valores Derivados con un


Disparador
CREATE PROCEDURE increment_salary
(id NUMBER, new_sal NUMBER) IS
BEGIN
UPDATE departments
SET
total_sal = NVL (total_sal, 0)+ new_sal
WHERE department_id = id;
END increment_salary;
CREATE OR REPLACE TRIGGER compute_salary
AFTER INSERT OR UPDATE OF salary OR DELETE
ON employees FOR EACH ROW
BEGIN
IF DELETING THEN
increment_salary(
:OLD.department_id,(-1*:OLD.salary));
ELSIF UPDATING THEN increment_salary(
:NEW.department_id,(:NEW.salary-:OLD.salary));
ELSE
increment_salary(
:NEW.department_id,:NEW.salary); --INSERT
END IF;
END;
Copyright 2004, Oracle. Todos los Derechos Reservados.

Registro de Eventos con un Disparador


CREATE OR REPLACE TRIGGER notify_reorder_rep
BEFORE UPDATE OF quantity_on_hand, reorder_point
ON inventories FOR EACH ROW
DECLARE
dsc product_descriptions.product_description%TYPE;
msg_text VARCHAR2(2000);
BEGIN
IF :NEW.quantity_on_hand <=
:NEW.reorder_point THEN
SELECT product_description INTO dsc
FROM product_descriptions
WHERE product_id = :NEW.product_id;
_ msg_text := 'ALERT: INVENTORY LOW ORDER:'||
'Yours,' ||CHR(10) ||user || '.'|| CHR(10);
ELSIF :OLD.quantity_on_hand >=
:NEW.quantity_on_hand THEN
msg_text := 'Product #'||... CHR(10);
END IF;
UTL_MAIL.SEND('inv@oracle.com','ord@oracle.com',
message=>msg_text, subject=>'Inventory Notice');
END;
Copyright 2004, Oracle. Todos los Derechos Reservados.

Copyright 2004, Oracle. Todos los Derechos Reservados.

Resumen
En esta leccin, debe haber aprendido lo siguiente:
Utilizar disparadores de base de datos o la
funcionalidad del servidor de base de datos para:

Mejorar la seguridad de la base de datos


Auditar cambios de datos
Forzar la integridad de los datos
Mantener la integridad referencial
Replicar datos entre tablas
Automatizar el clculo de datos derivados
Proporcionar funciones de registro de eventos

Reconocer cundo utilizar disparadores para la


funcionalidad de la base de datos
Copyright 2004, Oracle. Todos los Derechos Reservados.

Visin General de la Prctica C


No hay ninguna prctica para esta leccin.

Copyright 2004, Oracle. Todos los Derechos Reservados.

Potrebbero piacerti anche