Вы находитесь на странице: 1из 92

3

Creacin de Procedimientos

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Visin General de los Procedimientos


Un procedimiento es un bloque PL/SQL nombrado que realiza una accin. Un procedimiento puede estar almacenado en la base de datos (B.D.), como un objeto de la B.D, para ser ejecutado mltiples veces.

3-2

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Sintaxis para la Creacin Procedimientos


CREATE CREATE [OR [OR REPLACE] REPLACE] PROCEDURE PROCEDURE procedure_name procedure_name (argument1 (argument1 [mode1] [mode1] datatype1, datatype1, argument2 argument2 [mode2] [mode2] datatype2, datatype2, . .. .. . IS IS parte parte declarativa declarativa (OPCIONAL) (OPCIONAL) BEGIN BEGIN sentencias sentencias ejecutables ejecutables [EXCEPTION] [EXCEPTION] END; END;

3-3

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Modos de Parmetros Procedurales


Procedimiento

entorno de llamada

Parmetro IN Parmetro OUT Parmetro IN OUT


(DECLARE) BEGIN EXCEPTION END;

3-4

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Modos para Parmetros Formales


IN Por Defecto Valor que se pasa al Subprograma OUT Tiene que especif. Devuelve al entorno de llamada IN OUT Tiene que especif. Valor que se pasa al Subprograma; Devuelve al ent. de llamada Variable Inicializada Tiene que ser una variable

Parmetro formal constante

Parmetro Actual Tiene que ser una puede ser un variable literal, expresin, cosntate o variable inicializada
3-5

Variable no Inicializada

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Parmetros IN: Ejemplo


7369 v_id

SQL> SQL> CREATE CREATE OR OR REPLACE REPLACE PROCEDURE PROCEDURE raise_salary raise_salary 2 2 (v_id (v_id in in emp.empno%TYPE) emp.empno%TYPE) 3 3 IS IS 4 4 BEGIN BEGIN 5 UPDATE 5 UPDATE emp emp 6 SET sal 6 SET sal = = sal sal * * 1.10 1.10 7 WHERE 7 WHERE empno empno = = v_id; v_id; 8 8 END END raise_salary; raise_salary; 9 9 / / Procedure Procedure created. created. SQL> SQL> EXECUTE EXECUTE raise_salary raise_salary (7369) (7369) PL/SQL PL/SQL procedure procedure successfully successfully completed. completed.
3-6 Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Parmetros OUT: Ejemplo


Entorno de Llamada 7654 Proc. QUERY_EMP v_id MARTIN v_name 1250 1400 v_salary v_ comm

3-7

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Parmetros OUT: Ejemplo


SQL> SQL> 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12 12 CREATE CREATE OR OR REPLACE REPLACE PROCEDURE PROCEDURE query_emp query_emp (v_id IN emp.empno%TYPE, (v_id IN emp.empno%TYPE, v_name OUT v_name OUT emp.ename%TYPE, emp.ename%TYPE, v_salary v_salary OUT OUT emp.sal%TYPE, emp.sal%TYPE, v_comm OUT v_comm OUT emp.comm%TYPE) emp.comm%TYPE) IS IS BEGIN BEGIN SELECT ename, SELECT ename, sal, sal, comm comm INTO v_name, INTO v_name, v_salary, v_salary, v_comm v_comm FROM emp FROM emp WHERE empno WHERE empno = = v_id; v_id; END END query_emp; query_emp; / /

3-8

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Parmetros OUT y SQL*Plus


SQL> SQL> START START emp_query.sql emp_query.sql Procedure Procedure created. created. SQL> SQL> SQL> SQL> SQL> SQL> VARIABLE VARIABLE VARIABLE VARIABLE VARIABLE VARIABLE g_name g_name g_salary g_salary g_comm g_comm varchar2(15) varchar2(15) number number number number

SQL> SQL> EXECUTE EXECUTE query_emp query_emp (7654, (7654, :g_name, :g_name, :g_salary, :g_salary, 2 2 :g_comm) :g_comm) PL/SQL PL/SQL procedure procedure successfully successfully completed. completed. SQL> SQL> PRINT PRINT g_name g_name G_NAME G_NAME ----------------------------MARTIN MARTIN
3-9 Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Parmetros IN OUT
Calling environment
'(800)633-0575'

FORMAT_PHONE procedure
'(800)633-0575'

v_phone_no

SQL> CREATE OR REPLACE PROCEDURE format_phone 2 (v_phone_no IN OUT VARCHAR2) 3 IS 4 BEGIN 5 v_phone_no := '(' || SUBSTR(v_phone_no,1,3) || 6 ')' || SUBSTR(v_phone_no,4,3) || 7 '-' || SUBSTR(v_phone_no,7); 8 END format_phone; 9 /

3-10

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Paso de Parmetros: Procedimiento de Ejemplo


SQL> SQL> 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 CREATE CREATE OR OR REPLACE REPLACE PROCEDURE PROCEDURE add_dept add_dept (v_name (v_name IN IN dept.dname%TYPE dept.dname%TYPE DEFAULT DEFAULT 'unknown', 'unknown', v_loc IN DEFAULT v_loc IN dept.loc%TYPE dept.loc%TYPE DEFAULT 'unknown') 'unknown') IS IS BEGIN BEGIN INSERT INSERT INTO INTO dept dept VALUES VALUES (dept_deptno.NEXTVAL, (dept_deptno.NEXTVAL, v_name, v_name, v_loc); v_loc); END END add_dept; add_dept; / /

3-11

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Ejemplos: Paso de Parmetros

SQL> SQL> exec exec add_dept add_dept --- inserta inserta en en tabla tabla el el valor valor unknown unknown en en los los campos campos PL/SQL PL/SQL procedure procedure successfully successfully completed. completed. SQL> SQL> exec exec add_dept(TRAINING,NEW add_dept(TRAINING,NEW YORK); YORK);

SQL> SQL> DEPTNO DEPTNO ----------... ... 41 41 42 42 43 43 44 44


3-12

SELECT SELECT * * FROM FROM dept; dept; DNAME DNAME --------------------------... ... unknown unknown TRAINING TRAINING EDUCATION EDUCATION unknown unknown LOC LOC ------------------------... ... unknown unknown NEW NEW YORK YORK DALLAS DALLAS BOSTON BOSTON

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Llamada a un Proc. desde un bloque Annimo PL/SQL


DECLARE DECLARE v_id v_id NUMBER NUMBER := := 7900; 7900; BEGIN BEGIN raise_salary(v_id); raise_salary(v_id); COMMIT; COMMIT; ... ... END; END;

--invoke --invoke procedure procedure

3-13

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Llamada a un Proc. desde un Stored Procedure


SQL> SQL> CREATE CREATE OR OR REPLACE REPLACE PROCEDURE PROCEDURE process_emps process_emps 2 IS 2 IS 3 CURSOR 3 CURSOR emp_cursor emp_cursor IS IS 4 SELECT 4 SELECT empno empno 5 FROM emp; 5 FROM emp; 6 6 BEGIN BEGIN 7 FOR 7 FOR emp_rec emp_rec IN IN emp_cursor emp_cursor LOOP LOOP 8 raise_salary(emp_rec.empno); 8 raise_salary(emp_rec.empno); --invoke --invoke procedure procedure 9 END 9 END LOOP; LOOP; 10 COMMIT; 10 COMMIT; 11 11 END END process_emps; process_emps; 12 12 / /

3-14

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Borrado de Procedimientos en el Servidor


Usando SQL*Plus: Sintaxis:
DROP DROP PROCEDURE PROCEDURE procedure_name procedure_name

Ejemplo:
SQL> SQL> DROP DROP Procedure Procedure PROCEDURE PROCEDURE raise_salary; raise_salary; dropped. dropped.

3-15

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Resumen
Un procedimiento es un bloque nombrado PL/SQL que realiza una accin. Use parmetros para pasar datos desde el entorno de llamada al procedimiento. Los Procedimientos pueden ser llamados desde cualquier herramienta o lenguaje que soporte PL/SQL. Los Procedimientos pueden servir como bloques de una aplicacin.
3-16 Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

3
Creacin de Funciones

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Visin General de las Funciones Almacenadas


Una funcin es un bloque nombrado PL/SQL que devuelve un valor. Una funcin puede estar almacenada en la B.D, como objeto de la B.D, para repetidas ejecuciones. Una funcin puede ser llamada como parte de una expresin.

3-18

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Sintaxis para la Creacin de Funciones


CREATE CREATE [OR [OR REPLACE] REPLACE] (argument1 (argument1 [mode1] [mode1] argument2 argument2 [mode2] [mode2] . .. .. . RETURN RETURN datatype datatype IS|AS IS|AS PL/SQL PL/SQL Block; Block; FUNCTION FUNCTION FUNCTION_name FUNCTION_name datatype1, datatype1, datatype2, datatype2,

3-19

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Creacin de una Funcin Almacenada Usando SQL*Plus: Ejemplo SQL> CREATE OR REPLACE SQL> CREATE OR REPLACE FUNCTION FUNCTION get_sal get_sal
2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12 12 13 13 (v_id emp.empno%TYPE) (v_id IN IN emp.empno%TYPE) RETURN RETURN NUMBER NUMBER IS IS v_salary emp.sal%TYPE v_salary emp.sal%TYPE :=0; :=0; BEGIN BEGIN SELECT SELECT sal sal INTO v_salary INTO v_salary FROM emp FROM emp WHERE WHERE empno empno = = v_id; v_id; RETURN RETURN (v_salary); (v_salary); END END get_sal; get_sal; / /

3-20

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Ejecucin de Funciones
Llame a la funcin como parte de una expresin PL/SQL. Cree una variable host que recoja el valor devuelto. Ejecute la funcin. La variable host se volcar en valor de RETURN.

3-21

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Ejecucin de Funciones en SQL*Plus: Ejemplo


Entorno de Llamada
7934

Funcin GET_SAL
v_id RETURN v_salary

SQL> START get_salary.sql Procedure created. created SQL> SQL> VARIABLE VARIABLE g_salary g_salary number number SQL> SQL> EXECUTE EXECUTE :g_salary :g_salary := := get_sal(7934) get_sal(7934) PL/SQL PL/SQL procedure procedure successfully successfully completed. completed. SQL> SQL> PRINT PRINT g_salary g_salary G_SALARY G_SALARY ----------------------------------1300 1300
3-22 Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Desde dnde llamar a una Funcin de Usuario


Como columna de un SELECT Condiciones en clasulas WHERE y HAVING Clasulas CONNECT BY, START WITH, ORDER BY, y GROUP BY Clasula VALUES de un comando INSERT Clasula SET de un comando UPDATE
3-23 Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Llamada a Funciones desde Expresiones SQL: Restricciones


Una funcin de usuario tiene que ser una funcin almacenada. Tiene que ser una funcin de registro, no de grupo. Slo se sirve de comandos IN. Los tipos de datos tienen que ser CHAR, DATE, o NUMBER, no tipos PL/SQL types como BOOLEAN, RECORD, o TABLE. El tipo de Return tiene que ser un tipo interno del serividor Oracle.
3-24 Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Llamada a Funciones desde Expresiones SQL: Restricciones


No se permiten comandos INSERT, UPDATE, o DELETE. Las llamadas a subprogramas que rompan estas restricciones, tampoco se permiten.

3-25

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Borrando una Funcin del Servidor


Usando SQL*Plus Sintaxis:
DROP DROP FUNCTION FUNCTION FUNCTION_name FUNCTION_name

Ejemplo:
SQL> SQL> DROP DROP FUNCTION FUNCTION get_salary; get_salary; Function Function dropped. dropped.

3-26

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Procedimiento o Funcin?
Procedimiento Funcin

Entorno de llamada

IN argumento OUT argumento IN OUT argum.


(DECLARE) BEGIN EXCEPTION END;

Entorno de llamada

IN argumento

(DECLARE) BEGIN EXCEPTION END;

3-27

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Comparacin entre Procedimientos y Funciones


Procedimiento Se ejecuta como una sentencia PL/SQL No devuelve un tipo de dato Pueden devolver uno o ms valores Funcin Son llamadas como parte de una expresin Deben contener RETURN tipo de dato Tienen que devolver un valor

3-28

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Beneficios de Procedimientos y Funciones Almacenadas


Mejoran el Rendimiento Mejoran el Mantenimiento Mejoran la Seguridad e Integridad de los datos.

3-29

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Resumen
Una funcin es un bloque nombrado PL/SQL que tiene que devolver un valor. Una funcin es llamada como parte de una expresin. Una funcin almacenada puede ser llamada en sentencias SQL.

3-30

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

3
Creacin de Paquetes

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Visin General sobre los Paquetes


Agrupan de forma lgica conceptos PL/SQL relacionados; tipos PL/SQL, items y subprogramas Compuestos de dos partes:
Especificacin Cuerpo

No pueden ser llamados, parametrizados o anidados Permiten a Oracle8 leer mltiples objetos en memoria, de una sola vez.
3-32 Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Ventajas de los Paquetes


Modularidad Diseo ms sencilo de la aplicacin Informacin oculta Funcionalidad aadida Mejor rendimiento Sobrecarga

3-33

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Ventajas de los Paquetes


Modularidad Diseo ms sencilo de la aplicacin Informacin oculta Funcionalidad aadida Mejor rendimiento Sobrecarga

3-34

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Desarrollo de un Paquete
1
Especificacin del Paquete
Declaracin del Procedimiento A

4
Cuerpo del Paquete
Definicin del Procedimiento B Definicin del Procedimiento A

3-35

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Desarrollo de un Paquete
1
Especificacin del Paquete
Declaracin del Procedimiento A

4
Cuerpo del Paquete
Definicin del Procedimiento B Definicin del Procedimiento A

3-36

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Creacin de la Especificacin de un Paquete


Sintaxis:
CREATE CREATE [OR [OR REPLACE] REPLACE] PACKAGE PACKAGE package_name package_name IS IS | | AS AS public public type type and and item item declarations declarations subprogram subprogram specifications specifications END END package_name; package_name;

3-37

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Declaracin de Partes Pblicas


Paquete COMM_PACKAGE
G_COMM

Especificacin del Paquete

Declaracin del Procedimiento RESET_COMM

3-38

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Creacin de la Especificacin de un Paquete: Ejemplo


SQL>CREATE OR REPLACE PACKAGE comm_package IS 2 g_comm NUMBER := 10; --initialized to 10 3 PROCEDURE reset_comm 4 (v_comm IN NUMBER); 5 END comm_package; 6 /

3-39

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Declaracin de una Variable Global o un Procedimiento Pblico


SQL> EXECUTE comm_package.g_comm := 5 SQL> EXECUTE comm_package.reset_comm(8)

3-40

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Creacin del Cuerpo de un Paquete


Sintaxis:
CREATE CREATE [OR [OR REPLACE] REPLACE] PACKAGE PACKAGE BODY BODY package_name package_name IS IS | | AS AS private private type type and and item item declarations declarations subprogram subprogram bodies bodies END END package_name; package_name;

3-41

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Partes Pblicas y Privadas


Paquete COMM_PACKAGE Especificacin del Paquete
G_COMM Declaracin del Procedimiento RESET_COMM

1 2

Cuerpo del Paquete

Definicin de la Funcin VALIDATE_COMM Definicin del Procedimiento RESET_COMM

3-42

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Creacin del Cuerpo de un Paquete : Ejemplo


SQL>CREATE OR REPLACE PACKAGE BODY comm_package IS 2 FUNCTION validate_comm 3 (v_comm IN NUMBER) RETURN BOOLEAN 4 IS 5 v_max_comm NUMBER; 6 BEGIN 7 SELECT MAX(comm) 8 INTO v_max_comm 9 FROM emp; 10 IF v_comm > v_max_comm THEN RETURN(FALSE); 11 ELSE RETURN(TRUE); 12 END IF; 13 END validate_comm; 14 END comm_package; 15 /
3-43

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Creacin del Cuerpo de un Paquete : Ejemplo


SQL>PROCEDURE reset_comm 2 (v_comm IN NUMBER) 3 IS 4 v_valid BOOLEAN; 5 BEGIN 6 v_valid := validate_comm(v_comm); 7 IF v_valid = TRUE THEN 8 g_comm := v_comm; 9 ELSE 10 RAISE_APPLICATION_ERROR 11 (-20210,'Invalid commission'); 12 END IF; 13 END reset_comm; 14 END comm_package; 15 /

3-44

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Gua para el Desarrollo de Paquetes


Cree paquetes flexibles. Defina la especificacin del paquete antes que el cuerpo. La especificacin del paquete slo debera de contener construcciones pblicas La especificacin del paquete debera contener el mnimo n de construcciones.
3-45 Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Llamada a Programas de un Paquete


Ejemplo 1: Llamada a una funcin desde un procedimiento del mismo paquete:
CREATE OR REPLACE PACKAGE BODY comm_package IS . . . PROCEDURE reset_comm(v_comm IN NUMBER) IS v_valid BOOLEAN; BEGIN v_valid := validate_comm(v_comm); IF v_valid = TRUE THEN g_comm := v_comm; ELSE RAISE_APPLICATION_ERROR (-20210, 'Invalid comm'); END IF; END reset_comm; END comm_package;
3-46

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Llamada a Programas de un Paquete


Ejemplo 2: Llamada a un procedimiento de un paquete desde SQL*Plus:
SQL> EXECUTE comm_package.reset_comm(1500);

Ejemplo 3: Llamada a un procedimiento de un paquete en un esquema diferente:


SQL> EXECUTE scott.comm_package.reset_comm(1500);

Ejemplo 4: Llamada a un procedimiento de un paquete en una B.D. remota:


SQL> EXECUTE comm_package.reset_comm@ny (1500);

3-47

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Referencia a una Variable Global dentro del Paquete


Ejemplo 1:
CREATE OR REPLACE PACKAGE BODY comm_package IS . . . PROCEDURE reset_comm(v_comm IN NUMBER) IS v_valid BOOLEAN; BEGIN v_valid := validate_comm(v_comm); IF v_valid = TRUE THEN g_comm := v_comm; ELSE RAISE_APPLICATION_ERROR (-20210,'Invalid comm'); END IF; END reset_comm; END comm_package;

3-48

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Referencia a una Variable Global desde un Proc. Standalone


Ejemplo 2:
CREATE OR REPLACE PROCEDURE hire_emp (v_ename IN emp.ename%TYPE, v_mgr IN emp.mgr%TYPE, v_job IN emp.job%TYPE, v_sal IN emp.sal%TYPE) IS v_comm emp.comm%TYPE; . . . BEGIN . . . v_comm := comm_package.g_comm; . . . END hire_emp;

3-49

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Estado Persistente de las Variables de un Paquete


SCOTT-09:00> EXECUTE comm_package.reset_comm(120); Initially g_comm equals 10 After executing the procedure, g_comm equals 120 JONES-09:30> INSERT INTO emp (ename,..,comm) VALUES ('Madona',..,2000); JONES-09:35> EXECUTE comm_package.reset_comm(170); Initially g_comm equals 10 After executing the procedure, g_comm equals 170 SCOTT-10:00> EXECUTE comm_package.reset_comm(4000); Results in: 'Invalid commission' JONES-11:00> ROLLBACK; JONES-11:01> EXIT; JONES-12:00> EXECUTE comm_package.reset_comm(150); Initially g_comm equals 10 After executing the procedure, g_comm equals 150

3-50

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Estado Persistente de un Cursor en un Paquete


Ejemplo:
SQL> 2 3 4 5 6 7 8 CREATE OR REPLACE PACKAGE pack_cur IS CURSOR c1 IS SELECT empno FROM emp ORDER BY empno desc; PROCEDURE proc1_3rows; PROCEDURE proc4_6rows; END pack_cur; /

3-51

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Estado Persistente de un Cursor en un Paquete


SQL> CREATE OR REPLACE PACKAGE BODY pack_cur 2 IS 3 v_empno NUMBER; 4 PROCEDURE proc1_3rows IS 5 BEGIN OPEN c1; 6 LOOP FETCH c1 INTO v_empno; 7 DBMS_OUTPUT.PUT_LINE('Id :' ||(v_empno)); 8 EXIT WHEN c1%ROWCOUNT >= 3; 9 END LOOP; 10 END proc1_3rows; 11 PROCEDURE proc4_6rows IS 12 BEGIN 13 LOOP FETCH c1 INTO v_empno; 14 DBMS_OUTPUT.PUT_LINE('Id :' ||(v_empno)); 15 EXIT WHEN c1%ROWCOUNT >= 6; 16 END LOOP; 17 CLOSE c1; 18 END proc4_6rows; 19 END pack_cur; 20 /
3-52 Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Estado Persistente de un Cursor en un Paquete


SQL> SET SERVEROUTPUT ON SQL> EXECUTE pack1.proc1_3rows; Id : 7934 Id : 7902 Id : 7900 SQL> EXECUTE pack1.proc4_6rows; Id : 7876 Id : 7844 Id : 7839

3-53

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Estado Persistente de Tablas de Registros PL/SQL en un Paquete


CREATE OR REPLACE PACKAGE emp_package IS TYPE emp_table_type IS TABLE OF emp%ROWTYPE INDEX BY BINARY_INTEGER; PROCEDURE read_emp_table(emp_table OUT emp_table_type); END emp_package; CREATE OR REPLACE PACKAGE BODY emp_package IS PROCEDURE read_emp_table(emp_table OUT emp_table_type) IS i BINARY_INTEGER:=0; BEGIN FOR emp_record IN (SELECT * FROM emp) LOOP emp_table(i):=emp_record; I:=I+1; END LOOP; END; END emp_package;

3-54

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Eliminacin de Paquetes
Para borrar la especificacin del paquete y el cuerpo:
DROP DROP PACKAGE PACKAGE package_name package_name

Para borrar el cuerpo del paquete:


DROP DROP PACKAGE PACKAGE BODY BODY package_name package_name

3-55

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Resumen
Mejoran la organizacin, gestin, seguridad y rendimiento. Agrupan procedimientos y funciones. Se puede cambiar el cuerpo de un paquete sin que afecte a la especificacin. Conceden acceso de seguridad al paquete completo.

3-56

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Resumen
Ocultan el cdigo fuente a los usuarios. Cargan todo el paquete en memoria en la primera llamada. Reducen el acceso a disco para llamadas posteriores. Ofrecen identificadores para las sesiones de usuario.

3-57

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Resumen
Comando CREATE [OR REPLACE] PACKAGE CREATE [OR REPLACE] PACKAGE BODY DROP PACKAGE Tarea Crea o modifica la especificacin de un paquete ya existente Crea o modifica el cuerpo de un paquete ya existente Borra tanto la especificacin como el cuerpo de un paquete Borra el cuerpo de un paquete

DROP PACKAGE BODY

3-58

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

3
Creacin de Triggers en la Base de Datos

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Visin General de los Triggers


Un trigger es un bloque PL/SQL que se ejecuta implcitamente cuando ocurre un evento. Un trigger puede ser de la base de datos o de la aplicacin.

3-60

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Gua para el Diseo de Triggers


Realizar acciones relacionadas. Utilizar triggers para operaciones globales. No reinventar la rueda Prestar atencin a los excesos (overkill)

3-61

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Ejemplo de Trigger de la B.D.


Aplicacin
SQL> SQL> 2 2 INSERT INSERT INTO INTO EMP EMP . .. . .; .;

Tabla EMP
EMPNO ENAM 7838 E 7698 KING 7369 BLAK E 7788 SMIT H
3-62

Trigger CHECK_SAL
JOB PRESIDENT MANAGER CLERK ANALYST SAL 5000 2850 800 3000

SCOT T

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Creacin de Disparadores
Momento: BEFORE o AFTER Evento: INSERT o UPDATE o DELETE Nombre Tabla: On table Tipo de Trigger: Row o statement Clasula When: Condicin Cuerpo del Trigger: DECLARE BEGIN END;
3-63 Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Componentes de un Trigger
Momento: Cundo debera dispararse? BEFORE: El cdigo del cuerpo del trigger se ejecutar antes del evento DML AFTER: El cdigo del cuerpo del trigger se ejecutar antes del evento DML

3-64

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Componentes de un Trigger
Evento: Qu operacin DML provocar la ejecucin trigger? INSERT UPDATE DELETE Cualquier combinacin de las anteriores

3-65

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Componentes de un Trigger
Tipo de Trigger: Cuntas veces debera ejecutarse el cuerpo del trigger cuando ocurre el evento? Statement: El cuerpo del trigger se ejecuta slo una vez para el evento. Este es el comportamiento por defecto. Row: El cuerpo del trigger se ejecuta una vez para cada registro afectado por el evento.
3-66 Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Componentes de un Trigger
Cuerpo del Trigger: Qu accin debera de realizar el trigger? El cuerpo del trigger es definido con un bloque PL/SQL annimo [DECLARE] BEGIN [EXCEPTION] END;
3-67 Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Sintaxis para la Creacin y Definicin de Triggers


CREATE CREATE [OR [OR REPLACE] REPLACE] TRIGGER TRIGGER timing OR timing event1 event1 [ [ OR event2 event2 OR OR ON ON table_name table_name PL/SQL PL/SQL block; block; trigger_name trigger_name event3] event3]

3-68

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Trigger Before Statement: Ejemplo


SQL> SQL> 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12 12
3-69

CREATE CREATE OR OR REPLACE REPLACE TRIGGER TRIGGER secure_emp secure_emp BEFORE BEFORE INSERT INSERT ON ON emp emp BEGIN BEGIN IF IF (TO_CHAR (TO_CHAR (sysdate,'DY') (sysdate,'DY') IN IN ('SAT','SUN')) ('SAT','SUN')) OR OR (TO_CHAR(sysdate,'HH24')NOT (TO_CHAR(sysdate,'HH24')NOT BETWEEN BETWEEN '08' '08' AND AND '18' '18' THEN THEN RAISE_APPLICATION_ERROR RAISE_APPLICATION_ERROR (-20500, (-20500, 'You 'You may may only only insert insert into into EMP EMP during during normal normal hours.'); hours.'); END END IF; IF; END; END; / /
Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Ejemplo
SQL> SQL> 2 2 INSERT INSERT INTO INTO emp emp (empno, (empno, ename, ename, deptno) deptno) VALUES (7777, VALUES (7777, 'BAUWENS', 'BAUWENS', 40); 40); INSERT INSERT INTO INTO emp emp (empno, (empno, ename, ename, deptno) deptno) * * ERROR ERROR at at line line 1: 1: ORA-20500: ORA-20500: You You may may only only insert insert into into EMP EMP during during normal normal hours. hours. ORA-06512: ORA-06512: ORA-04088: ORA-04088: at at "SCOTT.SECURE_EMP", "SCOTT.SECURE_EMP", error error during during execution execution line line 4 4 of of trigger trigger

'SCOTT.SECURE_EMP' 'SCOTT.SECURE_EMP'

3-70

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Trigger After Statement: Ejemplo


SQL>CREATE SQL>CREATE OR OR REPLACE REPLACE TRIGGER TRIGGER check_salary_count check_salary_count 2 AFTER UPDATE OF sal ON emp 2 AFTER UPDATE OF sal ON emp 3 3 DECLARE DECLARE 4 4 v_salary_changes v_salary_changes NUMBER; NUMBER; 5 NUMBER; 5 v_max_changes v_max_changes NUMBER; 6 BEGIN 6 BEGIN 7 7 SELECT SELECT upd, upd, max_upd max_upd 8 8 INTO INTO v_salary_changes, v_salary_changes, v_max_changes v_max_changes 9 9 FROM FROM audit_table audit_table 10 10 WHERE WHERE user_name user_name = = user user 11 AND table_name = 11 AND table_name = 'EMP' 'EMP' 12 AND column_name = 12 AND column_name = 'SAL'; 'SAL'; 13 13 IF IF v_salary_changes v_salary_changes > > v_max_changes v_max_changes THEN THEN 14 RAISE_APPLICATION_ERROR 14 RAISE_APPLICATION_ERROR (-20501, (-20501, 15 'You 15 'You may may only only make make a a maximum maximum of of '|| '|| 16 TO_CHAR (v_max_changes) || 16 TO_CHAR (v_max_changes) || 17 ' 17 ' changes changes to to the the SAL SAL column'); column'); 18 18 END END IF; IF; 19 19 END; END; 20 / 20 /
3-71 Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Creacin de un Trigger a Nivel de Registro


CREATE CREATE [OR [OR REPLACE] REPLACE] TRIGGER TRIGGER trigger_name trigger_name timing OR timing event1 event1 [ [ OR event2 event2 OR OR event3] event3] ON ON table_name table_name [REFERENCING ] [REFERENCING OLD OLD AS AS old old | | NEW NEW AS AS new new ] FOR FOR EACH EACH ROW ROW [WHEN ] [WHEN condition condition ] PL/SQL PL/SQL block; block;

3-72

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Trigger After Row: Ejemplo


SQL>CREATE SQL>CREATE OR OR REPLACE REPLACE TRIGGER TRIGGER audit_emp audit_emp 2 AFTER DELETE OR INSERT OR UPDATE 2 AFTER DELETE OR INSERT OR UPDATE ON ON emp emp 3 FOR EACH ROW 3 FOR EACH ROW 4 4 BEGIN BEGIN 5 5 IF IF DELETING DELETING THEN THEN 6 UPDATE audit_table 6 UPDATE audit_table SET SET del del = = del del + +1 1 7 WHERE user_name = user AND table_name 7 WHERE user_name = user AND table_name = = 'EMP' 'EMP' 8 AND column_name IS NULL; 8 AND column_name IS NULL; 9 ELSIF INSERTING 9 ELSIF INSERTING THEN THEN 10 UPDATE audit_table 10 UPDATE audit_table SET SET ins ins = = ins ins + +1 1 11 WHERE user_name = user AND table_name 11 WHERE user_name = user AND table_name = = 'EMP' 'EMP' 12 AND column_name IS NULL; 12 AND column_name IS NULL; 13 ELSIF UPDATING 13 ELSIF UPDATING ('SAL') ('SAL') THEN THEN 14 UPDATE audit_table SET 14 UPDATE audit_table SET upd upd = = upd upd + +1 1 15 WHERE user_name = user AND table_name 15 WHERE user_name = user AND table_name = = 'EMP' 'EMP' 16 AND column_name = 'SAL'; 16 AND column_name = 'SAL'; 17 ELSE /* The 17 ELSE /* The data data manipulation manipulation operation operation is is a a general general UPDATE. UPDATE. */ */ 18 UPDATE audit_table SET upd = upd + 1 18 UPDATE audit_table SET upd = upd + 1 19 WHERE 19 WHERE user_name user_name = = user user AND AND table_name table_name = = 'EMP' 'EMP' 20 AND column_name IS NULL; 20 AND column_name IS NULL; 21 END IF; 21 END IF; 22 22 END; END; 23 / 23 /
3-73 Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Uso de los calificadores OLD y NEW


SQL>CREATE SQL>CREATE OR OR REPLACE REPLACE TRIGGER TRIGGER audit_emp_values audit_emp_values 2 2 AFTER AFTER DELETE DELETE OR OR INSERT INSERT OR OR UPDATE UPDATE ON ON emp emp 3 3 FOR FOR EACH EACH ROW ROW 4 4 BEGIN BEGIN 5 INSERT 5 INSERT INTO INTO audit_emp_values audit_emp_values (user_name, (user_name, 6 timestamp, 6 timestamp, id, id, old_last_name, old_last_name, new_last_name, new_last_name, 7 old_title, 7 old_title, new_title, new_title, old_salary, old_salary, new_salary) new_salary) 8 VALUES 8 VALUES (USER, (USER, SYSDATE, SYSDATE, :old.empno, :old.empno, :old.ename, :old.ename, 9 :new.ename, 9 :new.ename, :old.job, :old.job, :new.job, :new.job, 10 :old.sal, 10 :old.sal, :new.sal); :new.sal); 11 11 END; END; 12 12 / /
3-74

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Tabla de Auditora Audit_Emp_Values


USER_NAME EGRAVINA NGREENBE TIMESTAMP ID OLD_LAST_NAME NEW_LAST_NAME HUTTON TURNER 12-NOV-97 7950 NULL 10-DEC-97 7844 MAGEE

Continuacin
OLD_TITLE NULL CLERK NEW_TITLE ANALYST SALESMAN OLD_SALARY NULL 1100 NEW_SALARY 3500 1100

3-75

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Condicionando un Trigger de Registro


SQL>CREATE SQL>CREATE OR OR REPLACE REPLACE TRIGGER TRIGGER derive_commission_pct derive_commission_pct 2 2 BEFORE BEFORE INSERT INSERT OR OR UPDATE UPDATE OF OF sal sal ON ON emp emp 3 3 FOR FOR EACH EACH ROW ROW 4 4 WHEN WHEN (new.job (new.job = = 'SALESMAN') 'SALESMAN') 5 5 BEGIN BEGIN 6 6 IF IF INSERTING INSERTING THEN THEN :new.comm :new.comm := := 0; 0; 7 ELSE /* 7 ELSE /* UPDATE UPDATE of of salary salary */ */ 8 IF 8 IF :old.comm :old.comm IS IS NULL NULL THEN THEN 9 :new.comm 9 :new.comm :=0; :=0; 10 ELSE 10 ELSE 11 :new.comm 11 :new.comm := := :old.comm :old.comm * * (:new.sal/:old.sal); (:new.sal/:old.sal); 12 END 12 END IF; IF; 13 13 END END IF; IF; 14 14 END; END; 15 15 / /
3-76 Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Diferenciando entre Triggers y Procedimientos Almacenados


Triggers Usa CREATE TRIGGER El Dic. de Datos contiene el cdigo fuente y el p-code Invocados implcitamente NO se permite: COMMIT, SAVEPOINT, ROLLBACK Procedure Usa CREATE PROCEDURE El Dic. de Datos contiene el cdigo fuente y el p-code Invocados explcitamente Se permite: COMMIT, SAVEPOINT, ROLLBACK

3-77

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Gestin de los Triggers


Activar o desactivar un trigger de la B.D.
ALTER ALTER TRIGGER TRIGGER trigger_name trigger_name DISABLE DISABLE | | ENABLE ENABLE

Activar o desactivar todos los trigs. de una tabla


ALTER ALTER TABLE TABLE table_name table_name DISABLE DISABLE | | ENABLE ENABLE ALL ALL TRIGGERS TRIGGERS

Recompilar un trigger para una tabla


ALTER ALTER TRIGGER TRIGGER trigger_name trigger_name COMPILE COMPILE

3-78

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Eliminacin de Triggers
Para borrar un trigger de la B.D, utilice la sintaxis DROP TRIGGER:
DROP DROP TRIGGER TRIGGER trigger_name trigger_name

3-79

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Auditar por medio de la Utilidad Audit


SQL> SQL> 2 2 3 3 4 4 AUDIT AUDIT INSERT, INSERT, UPDATE, UPDATE, DELETE DELETE ON emp ON emp BY BY ACCESS ACCESS WHENEVER WHENEVER SUCCESSFUL; SUCCESSFUL;

3-80

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Auditar por medio de Triggers


SQL>CREATE SQL>CREATE OR OR REPLACE REPLACE TRIGGER TRIGGER audit_emp_values audit_emp_values 2 AFTER DELETE OR INSERT OR UPDATE 2 AFTER DELETE OR INSERT OR UPDATE ON ON emp emp 3 FOR EACH ROW 3 FOR EACH ROW 4 4 BEGIN BEGIN 5 5 IF IF audit_emp_package.g_reason audit_emp_package.g_reason IS IS NULL NULL THEN THEN 6 RAISE_APPLICATION_ERROR (-20059, 'Specify 6 RAISE_APPLICATION_ERROR (-20059, 'Specify a a reason reason 7 for the data operation with the procedure 7 for the data operation with the procedure 8 SET_REASON 8 SET_REASON before before proceeding.'); proceeding.'); 9 ELSE 9 ELSE 10 INSERT 10 INSERT INTO INTO audit_emp_values audit_emp_values (user_name, (user_name, timestamp, timestamp, id, id, 11 old_last_name, 11 old_last_name, new_last_name, new_last_name, old_title, old_title, new_title, new_title, 12 old_salary, 12 old_salary, new_salary, new_salary, comments) comments) 13 VALUES (user, sysdate, :old.empno,:old.ename, 13 VALUES (user, sysdate, :old.empno,:old.ename, 14 :new.ename, 14 :new.ename, :old.job, :old.job, :new.job, :new.job, :old.sal, :old.sal, 15 :new.sal, :audit_emp_package.g_reason); 15 :new.sal, :audit_emp_package.g_reason); 16 END IF; 16 END IF; 17 17 END; END; 18 / 18 / SQL>CREATE SQL>CREATE TRIGGER TRIGGER cleanup_audit_emp cleanup_audit_emp 2 2 AFTER AFTER INSERT INSERT OR OR UPDATE UPDATE OR OR DELETE DELETE ON ON emp emp 3 3 BEGIN BEGIN 4 4 audit_emp_package.g_reason audit_emp_package.g_reason := := NULL; NULL; 5 END; 5 END; 6 6/ /
3-81 Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Forzar la Integridad de los Datos dentro del Servidor


SQL> SQL> 2 2 ALTER ALTER TABLE TABLE emp emp ADD ADD CONSTRAINT CONSTRAINT ck_salary ck_salary CHECK CHECK (sal (sal >= >= 500); 500);

3-82

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Proteccin de la Integridad de los Datos con un Trigger


SQL>CREATE SQL>CREATE OR OR REPLACE REPLACE TRIGGER TRIGGER check_salary check_salary 2 2 BEFORE BEFORE UPDATE UPDATE OF OF sal sal ON ON emp emp 3 3 FOR FOR EACH EACH ROW ROW 4 4 WHEN WHEN (new.sal (new.sal < < old.sal) old.sal) OR OR 5 (new.sal 5 (new.sal > > old.sal old.sal * * 1.1) 1.1) 6 6 BEGIN BEGIN 7 RAISE_APPLICATION_ERROR 7 RAISE_APPLICATION_ERROR (-20508, (-20508, 8 'Do 8 'Do not not decrease decrease salary salary nor nor increase increase by by 9 more 9 more than than 10%.'); 10%.'); 10 10 END; END; 11 11 / /

3-83

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Forzar la Integridad Referencial dentro del Servidor


SQL> SQL> 2 2 3 3 4 4 ALTER ALTER TABLE TABLE emp emp ADD ADD CONSTRAINT CONSTRAINT emp_deptno_fk emp_deptno_fk FOREIGN FOREIGN KEY KEY (deptno) (deptno) REFERENCES REFERENCES dept(deptno) dept(deptno) ON ON DELETE DELETE CASCADE; CASCADE;

3-84

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Proteccin de la Integridad Referencial con un Trigger


SQL>CREATE SQL>CREATE OR OR REPLACE REPLACE TRIGGER TRIGGER cascade_updates cascade_updates 2 2 AFTER AFTER UPDATE UPDATE OF OF deptno deptno ON ON dept dept 3 3 FOR FOR EACH EACH ROW ROW 4 4 BEGIN BEGIN 5 UPDATE 5 UPDATE emp emp 6 SET emp.deptno 6 SET emp.deptno = = :new.deptno :new.deptno 7 WHERE 7 WHERE emp.deptno emp.deptno = = :old.deptno; :old.deptno; 8 8 END; END; 9 9/ /

3-85

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Replicacin de una Tabla dentro del Servidor


SQL> SQL> 2 2 CREATE CREATE SELECT SELECT SNAPSHOT SNAPSHOT emp_copy emp_copy AS AS * * FROM FROM emp@ny; emp@ny;

3-86

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Replicacin de una Tabla con un Trigger


SQL>CREATE SQL>CREATE OR OR REPLACE REPLACE TRIGGER TRIGGER emp_replica emp_replica 2 BEFORE INSERT OR UPDATE ON 2 BEFORE INSERT OR UPDATE ON emp emp 3 3 FOR FOR EACH EACH ROW ROW 4 4 BEGIN BEGIN /*Only /*Only proceed proceed if if user user init. init. data data operation, operation, 5 NOT the casc. trigger.*/ 5 NOT the casc. trigger.*/ 6 IF INSERTING 6 IF INSERTING THEN THEN 7 IF :new.flag 7 IF :new.flag IS IS NULL NULL THEN THEN 8 INSERT INTO emp@sf VALUES 8 INSERT INTO emp@sf VALUES (:new.empno, (:new.empno, 9 :new.ename,...,'B'); 9 :new.ename,...,'B'); 10 :new.flag 10 :new.flag = = 'A'; 'A'; 11 ELSE /* Updating. 11 ELSE /* Updating. */ */ 12 IF :new.flag = :old.flag 12 IF :new.flag = :old.flag THEN THEN 13 UPDATE emp@sf SET ename 13 UPDATE emp@sf SET ename = = :new.ename, :new.ename, ..., ..., 14 FLAG 14 FLAG = = :new.flag :new.flag 15 WHERE 15 WHERE empno empno = = :new.empno; :new.empno; 16 END IF; 16 END IF; 17 IF 17 IF :old.flag :old.flag = = 'A' 'A' THEN THEN :new.flag :new.flag := := 'B'; 'B'; 18 ELSE :new.flag := 'A'; 18 ELSE :new.flag := 'A'; 19 END 19 END IF; IF; 20 20 END END IF; IF; 21 21 END; END; 22 / 22 /

3-87

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Clculo de Datos Derivados dentro del Servidor


SQL> SQL> 2> 2> 3> 3> 4> 4> UPDATE UPDATE dept dept SET SET total_sal total_sal = = (SELECT (SELECT SUM(salary) SUM(salary) FROM FROM emp emp WHERE WHERE emp.deptno emp.deptno = = dept.deptno); dept.deptno);

3-88

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Clculo Datos Derivados con Triggers


SQL>CREATE SQL>CREATE OR OR REPLACE REPLACE PROCEDURE PROCEDURE increment_salary increment_salary 2 IN 2 (v_id (v_id IN dept.deptno%TYPE, dept.deptno%TYPE, 3 3 v_salary v_salary IN IN dept.total_salary%TYPE) dept.total_salary%TYPE) 4 IS 4 IS 5 5 BEGIN BEGIN 6 UPDATE 6 UPDATE dept dept 7 SET total_sal 7 SET total_sal = = NVL NVL (total_sal,0)+ (total_sal,0)+ v_salary v_salary 8 WHERE 8 WHERE deptno deptno = = v_id; v_id; 9 END increment_salary; 9 END increment_salary; 10 10 / / SQL>CREATE SQL>CREATE OR OR REPLACE REPLACE TRIGGER TRIGGER compute_salary compute_salary 2 AFTER INSERT OR UPDATE OF sal 2 AFTER INSERT OR UPDATE OF sal OR OR DELETE DELETE ON ON emp emp 3 3 FOR FOR EACH EACH ROW ROW 4 BEGIN 4 BEGIN 5 5 IF IF DELETING DELETING THEN THEN increment_salary(:old.deptno, increment_salary(:old.deptno, -1 -1 * * :old.sal); :old.sal); 6 ELSIF UPDATING THEN increment_salary(:new.deptno, 6 ELSIF UPDATING THEN increment_salary(:new.deptno, 7 :new.sal-:old.sal); 7 :new.sal-:old.sal); 8 ELSE /*inserting*/ increment_salary(:new.deptno, 8 ELSE /*inserting*/ increment_salary(:new.deptno, :new.sal); :new.sal); 9 END IF; 9 END IF; 10 10 END; END; 11 / 11 /
3-89 Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Control de Eventos con un Trigger


SQL>CREATE SQL>CREATE OR OR REPLACE REPLACE TRIGGER TRIGGER notify_reorder_rep notify_reorder_rep 2 AFTER UPDATE OF amount_in_stock, 2 AFTER UPDATE OF amount_in_stock, reorder_point reorder_point ON ON inventory inventory 3 FOR EACH ROW 3 FOR EACH ROW 4 4 WHEN WHEN new.amount_in_stock new.amount_in_stock <= <= new.reorder_point new.reorder_point 5 DECLARE 5 DECLARE 6 v_descrip product.descrip%TYPE; 6 v_descrip product.descrip%TYPE; 7 v_msg_text VARCHAR2(2000); 7 v_msg_text VARCHAR2(2000); 8 BEGIN 8 BEGIN 9 9 SELECT SELECT descrip descrip INTO INTO v_descrip v_descrip 10 FROM PRODUCT WHERE prodid 10 FROM PRODUCT WHERE prodid = = :new.product_id; :new.product_id; 11 v_msg_text := 'It has come to 11 v_msg_text := 'It has come to my my personal personal attention attention that, that, 12 due to recent ' 12 due to recent ' 13 CHR(10) 13 CHR(10) || || 'transactions, 'transactions, our our inventory inventory for for product product # # '|| '|| 14 TO_CHAR(:new.product_id)||'--' 14 TO_CHAR(:new.product_id)||'--' 15 || 15 || v_name v_name ||'-||'-- has has fallen' fallen' || || CHR(10) CHR(10) || || CHR(10) CHR(10) || || 16 'Yours,' ||CHR(10) ||user || '.'; 16 'Yours,' ||CHR(10) ||user || '.'; 17 dbms_mail.send 17 dbms_mail.send ('Inventory', ('Inventory', user,null,null,'Low user,null,null,'Low 18 Inventory',null,v_msg_text); 18 Inventory',null,v_msg_text); 19 END; 19 END; 20 20 / /
3-90

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Ventajas de los Triggers de la B.D.


Seguridad de los datos mejorada: Ofrecen chequeos de seguridad basada en valores. Ofrecen auditoras basadas en valores. Integridad de los datos mejorada: Fuerzan restricciones dinmicas de integridad de datos. Fuerzan restricciones complejas de integridad referencial. Aseguran que las operaciones relacionadas se realizan juntas de forma impcita.
3-91 Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Resumen
Procedimiento
xxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxx vvvvvvvvvvvvvvvvvv vvvvvvvvvvvvvvvvvv xxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxx vvvvvvvvvvvvvvvvvv vvvvvvvvvvvvvvvvvv xxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxx vvvvvvvvvvvvvvvvvv vvvvvvvvvvvvvvvvvv xxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxx vvvvvvvvvvvvvvvvvv vvvvvvvvvvvvvvvvvv xxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxx vvvvvvvvvvvvvvvvvv vvvvvvvvvvvvvvvvvv xxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxx vvvvvvvvvvvvvvvvvv vvvvvvvvvvvvvvvvvv xxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxx

Paquete Declaracin del Procedimiento A Definicin del Procedimiento B Definicin del Procedimiento A
Variable Local

Trigger

3-92

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Вам также может понравиться