Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
PL/ SQL
Mdulo 2
PL-SQL
OL-ORACLE02T
PL/ SQL
Mdulo 2
Dirigido a:
Desarrolladores de aplicaciones. Analistas/Programadores. Administradores de Base de Datos. Tcnicos de Sistemas
Duracin:
Dos semanas de autoestudio
Propsito:
Introducir al alumno en el conocimiento del lenguaje de programacin PL/ SQL como lenguaje del motor de base de datos Oracle. Conocer las estructuras y sentencias de control bsicas y su uso en bases de datos. Aprender el uso y ventajas de los elementos de programacin almacenados en la base datos: procedimientos, funciones, paquetes y triggers
OL-ORACLE02T Contenido
PL/ SQL
Mdulo 2
PL/SQL ........................................................................................................................................... 4 Caractersticas ............................................................................................................................... 5 Ventajas......................................................................................................................................... 6 Elementos del lenguaje.................................................................................................................. 7 Bloques PL / SQL ............................................................................................................................ 8 Tipos de Bloques............................................................................................................................ 9 Variables...................................................................................................................................... 10 Tipos de Datos Escalares .............................................................................................................. 11 Declaracin de Variables.............................................................................................................. 11 El Atributo %TYPE ........................................................................................................................ 12 El atributo %ROWTYPE................................................................................................................. 12 Variables Boolean ........................................................................................................................ 13 Mostrar mensajes: DBMS_OUTPUT.PUT_LINE.............................................................................. 14 Entorno de trabajo, el primer programa....................................................................................... 15 Lectura de variables por teclado, las variables & .......................................................................... 18 Funciones SQL.............................................................................................................................. 22 Utilizables en sentencias procedurales:........................................................................................ 22 No utilizables en sentencias procedurales:................................................................................... 22 Operadores.................................................................................................................................. 25 SELECT ......................................................................................................................................... 26 Manipulacin de Datos ................................................................................................................ 27 La sentencia MERGE ......................................................................... Error! Marcador no definido. Estructuras de Control ................................................................................................................. 28 Flujo de control............................................................................................................................ 28 Sentencia if: ................................................................................................................................. 28 Sentencia CASE ............................................................................................................................ 30 Control Iterativo: Sentencias LOOP .............................................................................................. 32 Tipos de Datos Compuestos ......................................................................................................... 36 Cursores ...................................................................................................................................... 43
OL-ORACLE02T
PL/ SQL
Mdulo 2
PL/SQL
Es la respuesta de Oracle a las limitaciones de SQL. Es un lenguaje de programacin estructurado que combina sentencias SQL con bucles, sentencias de control,... Es especfico de Oracle, por lo que su uso no es vlido en otras bases de datos. PL/SQL es un sofisticado lenguaje de programacin que se utiliza para acceder a bases de datos Oracle desde distintos entornos. PL/SQL est integrado con el servidor de base de datos, de modo que el cdigo PL/SQL puede ser procesado de forma rpida y eficiente. PL/SQL combina la potencia y flexibilidad de un lenguaje SQL con las estructuras procedimentales de un 3GL.
OL-ORACLE02T
PL/ SQL
Mdulo 2
Caractersticas
Juega un papel central tanto en las herramientas de Oracle (Developer, Forms, ...) como en el propio servidor (a travs de funciones, triggers, ... almacenados en el propio servidor). El motor PL/SQL presente tanto en las herramientas como en el servidor, filtra las sentencias SQL incluidas en los programas y las enva a la Base de Datos, procesando el resto de las sentencias procedurales en el propio motor con datos que son internos a la aplicacin, lo que reduce las consultas a la base de datos. PL/SQL ampla la funcionalidad de SQL aadiendo estructuras de las que pueden encontrarse en otros lenguajes procedimentales, como: Variables y tipos (tanto predefinidos como definidos por el usuario). Estructuras de control, como bucles y rdenes IF-THEN-ELSE. Procedimientos y funciones. Tipos de objetos y mtodos (en PL/SQL versin 8 o superior).
Las construcciones procedimentales estn perfectamente integradas con Oracle SQL, lo que da como resultado un lenguaje potente y estructurado.
OL-ORACLE02T
PL/ SQL
Mdulo 2
Ventajas
La modularizacin que caracteriza a los programas escritos en PL/SQL permite: Agrupar sentencias relacionadas lgicamente, en bloques. Anidar subbloques en bloques mayores para desarrollar aplicaciones complejas. Guardar los programas en libreras reutilizables. PL/SQL permite controlar los errores. Almacenamiento de unidades de programacin (procedimientos, funciones, paquetes, triggers) Los procedimientos, funciones y paquetes almacenados pueden ser invocados desde herramientas (Forms, Developer) o desde la propia consola.
PL/SQL integra tanto las estructuras procedimentales necesarias como el acceso a bases de datos. El resultado es un lenguaje robusto y potente, bien adaptado al diseo de aplicaciones complejas. Su capacidad de reutilizacin, de poderse almacenar en paquetes y su control de las excepciones. Su conocimiento permite el acceso a las distintas herramientas de Oracle que lo utilizan.
OL-ORACLE02T
PL/ SQL
Mdulo 2
Literales y comentarios Los literales de caracteres y fechas deben ir entre comillas simples. Los nmeros pueden ser valores simples o cientficos. Un slash (/) ejecuta la sentencia contenida en un Script o en el entorno SQL . -- Marca comentarios de una lnea. / * Delimita comentarios de ms de una lnea */
OL-ORACLE02T
PL/ SQL
Mdulo 2
Bloques PL / SQL
Los programas en PL/SQL pueden ser tambin llamados bloques PL/SQL. Pueden tener un nombre esto es, ser un procedimiento, una funcin, un paquete o un trigger o ser un bloque PL annimo. La estructura de un programa sea del tipo que sea es la siguiente: DECLARE declaraciones (variables, cursores, excepciones definidas por el usuario) BEGIN sentencias del programa (PL / SQL y SQL) EXCEPTION Procedimientos a seguir en caso de excepciones END ;
DECLARE mi_variable NUMBER (5); BEGIN SELECT salario INTO mi_variable FROM empleados WHERE numero_empleado = 1234; EXCEPTION WHEN nombre_excepcin THEN ... END;
OL-ORACLE02T
PL/ SQL
Mdulo 2
Tipos de Bloques
Annimos Subprogramas: Procedimientos, Funciones Annimos [DECLARE] BEGIN --sentencias [EXCEPTION] END ; Subprogramas Procedimientos PROCEDURE nombre IS BEGIN --sentencias [EXCEPTION] END ; Funciones FUNCTION nombre RETURN tipo IS BEGIN --sentencias [EXCEPTION] END ;
OL-ORACLE02T
PL/ SQL
Mdulo 2
Variables
Las variables pueden utilizarse para el almacenamiento temporal de datos, trabajar con valores almacenados, ser usadas repetidamente, etc... Se declaran e inicializan en la seccin de declaraciones. Se les asignan nuevos valores en la seccin de ejecucin. Se les pueden pasar valores a travs de parmetros. Se inicializan a nulo. Tipos de Variables Variables PL / SQL: Escalares slo pueden recoger un valor. Compuestas recogen fila o filas. Referencias punteros que apuntan a objetos de otros programas. LOB (large objects) contienen localizadores que indican la localizacin de objetos de gran tamao (por ejemplo imgenes).
10
OL-ORACLE02T
PL/ SQL
Mdulo 2
Declaracin de Variables
Dos variables pueden tener el mismo nombre si pertenecen a dos bloques distintos. El identificador debera ser distinto a los nombres de las columnas de la tabla usada en el bloque. Ejemplos: v_job VARCHAR2 (9); cuenta BINARY_INTEGER NOT NULL : = 0; fecha_fut DATE : = SYSDATE + 7; factor CONSTANT NUMBER (3,2) : = 8.25 ;
11
OL-ORACLE02T
PL/ SQL
Mdulo 2
El Atributo %TYPE
Define el tipo de la variable en funcin del de una columna de una tabla, o del de una variable previamente declarada.
El atributo %ROWTYPE
Lo utilizaremos normalmente con cursores (se ven ms adelante), en el ejemplo definimos una variable que es del mismo tipo que lo que haya en la tabla DEPT. Se utiliza para copiar la estructura de campos y de tipos de datos de una variable que es una tabla a otra. VARIABLE_TABLE DEPT%ROWTYPE;
12
OL-ORACLE02T
PL/ SQL
Mdulo 2
Variables Boolean
nicamente se les pueden asignar los valores TRUE, FALSE y NULL. Para realizar comprobaciones entre variables de este tipo se utilizan los operadores AND, OR y NOT. Se pueden utilizar expresiones aritmticas, caracteres o fechas para conseguir un valor boolean. EJEMPLO: DECLARE ENCONTRADO BOOLEAN :=FALSE; BEGIN IF A=.. THEN ENCONTRADO := TRUE.
13
OL-ORACLE02T
PL/ SQL
Mdulo 2
14
OL-ORACLE02T
PL/ SQL
Mdulo 2
Una vez dentro del sql*plus lanzar el comando: SET SERVEROUTPUT ON. Este comando pertenece al entorno sql*plus no es una sentencia PL/SQL por lo tanto deber ir fuera de los programas. Sirve para habilitar la salida de mensajes por pantalla y deber ponerse en cada nueva conexin.
15
OL-ORACLE02T
PL/ SQL
Mdulo 2
16
OL-ORACLE02T
PL/ SQL
Mdulo 2
2) Y ahora lo ejecutaremos. Esto puede hacerse de dos maneras: a. copiar y pegar directamente en sql*plus
b. Ejecutando el fichero con: @c:\hola_mundo.sql (suponermos que est guardado con extensin sql en el directorio c:)
17
OL-ORACLE02T
PL/ SQL
Mdulo 2
Podemos decir que ni la entrada de datos (con &), ni la salida de mensajes con DBMS_OUTPUT son muy sofisticados en este lenguaje. Es necesario tener en cuenta que se trata de un lenguaje enfocado al tratamiento masivo de la informacin.
18
OL-ORACLE02T
PL/ SQL
Mdulo 2
El programa es el siguiente:
BEGIN -- ESTE ES EL SEGUNDO PROGRAMA -- NO TIENE PARTE DECLARATIVA -- NI DE EXCEPCIONES -- ES PARA DEMOSTRAR COMO SE LEEN VARIABLES -- NOMBRE SE CONSIDERA DE TIPO CARCTER Y AOS -- NUMRICA
DBMS_OUTPUT.PUT_LINE('BUENOS DIAS ' || '&NOMBRE' || ' TIENES ' || &AOS || ' AOS '); END; /
19
OL-ORACLE02T
PL/ SQL
Mdulo 2
20
OL-ORACLE02T
PL/ SQL
Mdulo 2
Quiz un poco liosa no?. Vamos a eliminar los mensajes de antiguo nuevo. Para ello lanzaremos el comando: SET VERIFY OFF. La salida queda de la siguiente manera:
21
OL-ORACLE02T
PL/ SQL
Mdulo 2
Ejemplo de funciones SQL Concatenando datos en una cadena con espacios en blanco: v_nombre_completo := v_nombre|| || v_primer_apellido || || v_segundo_apellido; Utilizando la conversin a minsculas: v_nombre := LOWER(v_nombre);
22
OL-ORACLE02T
PL/ SQL
Mdulo 2
Funciones de conversin Las funciones tiene el mismo funcionamiento que en SQL , as: DECLARE v_date DATE := TO_DATE(12,ENE,99,DD,MON,YY); BEGIN... La sentencia : V_date:= Enero 20, 1999 Sera errnea
23
OL-ORACLE02T
PL/ SQL
Mdulo 2
Bloques Anidados Los bloques se pueden anidar en cualquier sitio que se permitan sentencias ejecutables, convirtindose el bloque en una sentencia. Caractersticas
Una seccin EXCEPTION puede contener bloques anidados, es decir, ser compartida por todos los bloques anidados. El mbito de un identificador es la zona en la que se puede referenciar ese identificador. Un identificador es visible para el bloque que ha sido declarado y para sus bloques anidados.
mbitos .... X NUMBER; BEGIN .... DECLARE aunque puede hacerse no es una buena prctica. y NUMBER(7); mbito de x BEGIN y:=x; mbito de y END; .... END;
24
OL-ORACLE02T
PL/ SQL
Mdulo 2
Operadores
Operador de Asignacin Operador de Concatenacin Operadores Aritmticos := || +,-,*,/,**(potencia), resto de la divisin entre A y B mod(A,B) Operadores de Relacin =,>,<,>=,<=, IN (contenido), NOT IN, BETWEEN, NOT BETWEEN, LIKE, NOT LIKE, IS NULL, IS NOT NULL Operadores Lgicos AND, NOT ,OR
25
OL-ORACLE02T
PL/ SQL
Mdulo 2
Interaccin con el servidor Oracle Sentencias SQL La extraccin de datos de la base de datos se realiza a travs del uso de sentencias SELECT. El cambio de datos en las filas de las tablas se realiza a travs de comandos DML. El control de transacciones se lleva a cabo con los comandos COMMIT, ROLLBACK o SAVEPOINT. Formato general: SELECT expresion INTO {var1[,var2] | registro } FROM nombre_tabla [WHERE condicin];
SELECT
La clasula INTO es imprescindible, es necesario guardar el valor ledo en una variable. Todas las instrucciones SELECT tienen que llevar un INTO a excepcin de los cursores. Las bsquedas deben devolver slo una fila. Cuando devuelven ms es necesario usar otra estructura de datos. DECLARE suma NUMBER(10,2); departamento VARCHAR2(3) : =20; BEGIN SELECT SUM(sal) INTO suma FROM emp WHERE deptno = departamento; DBMS_OUTPUT.PUT_LINE(El total es || suma); END; /
26
OL-ORACLE02T
PL/ SQL
Mdulo 2
Manipulacin de Datos
Se realiza con los comando INSERT, UPDATE y DELETE de SQL, pudiendo combinarlo con el uso de variables, etc.. DECLARE incremento emp.sal%TYPE : = 50; BEGIN UPDATE emp SET sal = sal + incremento WHERE deptno = 20; END; /
27
OL-ORACLE02T
PL/ SQL
Mdulo 2
Sentencia IF:
La ejecucin lgica de un programa se puede cambiar con el uso del condicional IF. IF THEN END IF IF THEN ELSE END IF IF THEN ELSIF END IF
28
OL-ORACLE02T
PL/ SQL
Mdulo 2
IF MULTIPLE IF CONDIDION THEN SENTENCIA/S; ELSIF CONDICION1 THEN SENTENCIA/S; ELSIF CONDICION2 THEN SENTENCIA2/S; ELSE SENTENCIA/S; END IF;
29
OL-ORACLE02T
PL/ SQL
Mdulo 2
30
OL-ORACLE02T
PL/ SQL
Mdulo 2
Manejando Valores Nulos Al trabajar con valores nulos, se pueden evitar algunos errores si se tiene en cuenta: Las comparaciones simples que incluyen nulls, siempre devuelven null. Aplicar el operador lgico NOT a un campo null devuelve null. En una sentencia de control condicional, si la condicin devuelve null , las secuencia asociada de sentencias, no se ejecuta.
31
OL-ORACLE02T
PL/ SQL
Mdulo 2
Loop Bsico es conveniente cuando las sentencias se deban ejecutar al menos una vez. Loop FOR se usa cuando se conoce el nmero de iteraciones.
32
OL-ORACLE02T
PL/ SQL
Mdulo 2
Ejemplo para mostrar por pantalla los 50 primeros nmeros. Se realiza con los tres tipos de bubles.
Bucle Bsico DECLARE -- SACAR POR PANTALLA LOS 50 PRIMEROS NUMEROS -- CON LOOP CONTADOR NUMBER(2):= 1; BEGIN LOOP DBMS_OUTPUT.PUT_LINE(CONTADOR); EXIT WHEN CONTADOR = 50; CONTADOR := CONTADOR +1; END LOOP; END; /
33
OL-ORACLE02T
PL/ SQL
Mdulo 2
Bucle WHILE
DECLARE V_CONT BEGIN V_CONT :=0; WHILE V_CONT<50 LOOP DBMS_OUTPUT.PUT_LINE(V_CONT); V_CONT:=V_CONT + 1; END LOOP; END; / NUMBER;
34
OL-ORACLE02T
PL/ SQL
Mdulo 2
Bucle FOR DECLARE -- SACAR POR PANTALLA LOS 50 PRIMEROS NUMEROS -- CON FOR BEGIN FOR I IN 1..50 LOOP DBMS_OUTPUT.PUT_LINE(I); END LOOP; END; / DECLARE -- SACAR POR PANTALLA LOS NUMEROS DEL 50 AL 1 -- CON FOR BEGIN FOR I IN REVERSE 1..50 LOOP DBMS_OUTPUT.PUT_LINE(I); END LOOP; END; /
35
OL-ORACLE02T
PL/ SQL
Mdulo 2
36
OL-ORACLE02T
PL/ SQL
Mdulo 2
Registros
Son estructuras de datos que agrupan informacin de una tabla o de otro registro y que se tratan como una unidad lgica. Son convenientes para recoger datos de una fila para su procesamiento. Ejemplo: .... TYPE datos_personales IS RECORD ( nombre VARCHAR2(10), apellido VARCHAR2(10), edad NUMBER (3) ); Registro1 datos_personales; .... declaracin de tipo de dato
37
OL-ORACLE02T
PL/ SQL
Mdulo 2
Tablas
Son matrices dinmicas, compuestas por un ndice y una columna de tipo escalar o registro. Sintaxis: DECLARE TYPE nombre_tabla IS TABLE OF (tipo_columna | variable%TYPE | | tabla.%ROWTYPE INDEX BY BINARY_INTEGER; identificador nombre_tabla; .... Ejemplo de declaracin: DECLARE T_MESES IS TABLE OF NUMBER(5) INDEX BY BINARY_INTEGER; GANACIAS T_MESES;
38
OL-ORACLE02T
PL/ SQL
Mdulo 2
DECLARE -- PROGRAMA DE EJEMPLO DE UTILIZACIN DE TABLAS TYPE TABLA IS TABLE OF NUMBER(5) INDEX BY BINARY_INTEGER; -- DECLARAMOS DOS VARIABLES DEL TIPO TABLA NUMEROS_1 TABLA; NUMEROS_2 TABLA; -- DECLARAMOS EL NDICE XBINARY_INTEGER; VALOR NUMBER(5):=0; BEGIN -- ASIGNAR VALORES DIRECTAMENTE NUMEROS_1(1) :=100; NUMEROS_1(2) :=200; NUMEROS_1(3) :=300; -- ASIGNAR VALORES CON UN BUCLE FOR X IN 1..3 LOOP VALOR:=VALOR+100; NUMEROS_2(X) :=VALOR; END LOOP;
39
OL-ORACLE02T
PL/ SQL
Mdulo 2
-- MOSTRAMOS LOS VALORES INTRODUCIDOS EN LAS DOS TABLAS FOR X IN 1..3 LOOP DBMS_OUTPUT.PUT_LINE('TABLA 1 ELEMENTO ' || X || ' = ' || NUMEROS_1(X)); DBMS_OUTPUT.PUT_LINE('TABLA 2 ELEMENTO ' || X || ' = ' || NUMEROS_2(X)); END LOOP; -- OPERAMOS CON LOS ELEMENTOS DE LA TABLA NUMEROS_1(1) :=VALOR*NUMEROS_2(3); -- MOSTRAMOS EL RESULTADO DBMS_OUTPUT.PUT_LINE('TABLA 1 ELEMENTO 1 ' || NUMEROS_1(1)); END;
40
OL-ORACLE02T
PL/ SQL
Mdulo 2
Atributos de las Tablas Una tabla est compuesta por una serie de elementos y se puede recorrer con un ndice que no tiene por qu ser consecutivo. Es por ello que para poder recorrerla se necesitan una serie de atributos, para acceder a ellos: Nombre_tabla.atributo_al_que_acceder COUNT indica el nmero de elementos que una tabla contiene. Tabla1.count; DELETE Tabla1.delete elimina todos los elementos. Tabla1.delete(4) elimina un elemento determinado. Tabla1.delete(4,7) elimina un rango de elementos.. EXISTS devuelve true si un elemento de la tabla existe. Tabla1.exists(7); FIRST LAST NEXT PRIOR devuelve el ndice del primer elemento de la tabla devuelve el ndice del ltimo elemento de la tabla devuelve el ndice del elemento inmediatamente posterior al de ndice i devuelve el ndice del elemento inmediatamente anterior al de ndice i
41
OL-ORACLE02T
PL/ SQL
Mdulo 2
Ejemplo de Tablas de registros SET SERVEROUTPUT ON DECLARE TYPE emp_table_type is table of employees%ROWTYPE INDEX BY BINARY_INTEGER; my_emp_table emp_table_type; v_count NUMBER(3) := 104; BEGIN FOR i IN 100 .. v_count LOOP SELECT INTO my_emp_table(i) FROM employees WHERE employee_id = i; -- ASUME QUE EXISTEN LOS EMPLEADOS CON NMEROS DEL 100 AL 104 -- SI NO ES AS, LA SELECT FALLARA END LOOP; FOR i IN my_emp_table.FIRST .. my_emp_table.LAST LOOP DBMS_OUTPUT.PUT_LINE(my_emp_table(i).last_name); END LOOP; END;
42
OL-ORACLE02T
PL/ SQL
Mdulo 2
Cursores
Cuando se ejecuta una sentencia SQL el servidor abre un rea de memoria en la que el comando se lleva a cabo, esa rea es el cursor. Hay dos tipos de cursor:
43
OL-ORACLE02T
PL/ SQL
Mdulo 2
Cursores implcitos
Para manejar un cursor tenemos unos atributos: SQL%FOUND, Devuelve verdadero si el cursor tiene alguna fila, falso en caso contrario. SQL%NOTFOUND Verdadero si el cursor no ha devuelto ninguna fila. SQL%ROWCOUNT, nmero de filas al que afecta la operacin.
Si una sentencia SELECT no encuentra filas genera una excepcin, que es un tipo de error que puede ser tratado o no, el error es NO_DATA_FOUND.
44
OL-ORACLE02T
PL/ SQL
Mdulo 2
Ejemplo Cursor Implcito Doblar el salario al empleado 7902 si existe, si no existe se inserta en la tabla EMP
BEGIN UPDATE EMP SET SAL=SAL *2 WHERE EMPNO=7902; IF SQL%NOTFOUND THEN INSERT INTO EMP(EMPNO,ENAME,JOB) VALUES (1234,'LUIS ', 'ANALISTA '); END IF; END; /
45
OL-ORACLE02T
PL/ SQL
Mdulo 2
Cursores explcitos
Es el mecanismo de PL/SQL para tratar individualmente el conjunto de filas recuperado por una sentencia SELECT. Es una estructura en memoria que recupera filas de 1 o varias tablas, donde se accede a los datos de forma secuencial. Los cursores se tratan de la siguiente forma: 1. Declaracin del cursor 2. Apertura del cursor 3. Recogida de datos en variables PL 4. Cierre del cursor. Son definidos por el programador.
46
OL-ORACLE02T
PL/ SQL
Mdulo 2
47
OL-ORACLE02T
PL/ SQL
Mdulo 2
Apertura Tras haberlo declarado, el cursor se abre con la sentencia OPEN nombre_cursor; dentro de la seccin ejecutable. Al abrir el cursor se ejecuta el SELECT y almacena el resultado en la memoria principal, el cursor queda apuntando a la primera fila. Se puede abrir un cursor varias veces seguidas, lo que servira para ver si ha habido actualizaciones. Ejemplo: DECLARE CURSOR C1 IS SELECT * FROM empleados WHERE salario BETWEEN 1000 AND 2000; VAR_C1 C1%ROWTYPE; .... BEGIN OPEN C1; ..
48
OL-ORACLE02T
PL/ SQL
Mdulo 2
Extraccin La extraccin de las filas para su tratamiento se realiza con la clasula FETCH:
FETCH nombre_cursor INTO variable1 [,variable2,...]; coincidir. FETCH nombre_cursor INTO registro;
Ejemplo: DECLARE CURSOR C1 IS SELECT * FROM empleados WHERE salario BETWEEN 1000 AND 2000; VAR_C1 C1%ROWTYPE; .... BEGIN OPEN C1; FETCH C1 INTO VAR_C1; .
49
OL-ORACLE02T
PL/ SQL
Mdulo 2
Cierre Cuando se han recorrido todas las filas con FETCH, se debe cerrar el cursor para liberar memoria. La clusula CLOSE cierra el cursor. Ejemplo: DECLARE CURSOR C1 IS SELECT * FROM empleados WHERE salario BETWEEN 1000 AND 2000; VAR_C1 C1%ROWTYPE; .... BEGIN OPEN C1; FETCH C1 INTO VAR_C1; . CLOSE C1;
50
OL-ORACLE02T
PL/ SQL
Mdulo 2
Atributos devuelve true si el ltimo FETCH efectuado devolvi una nueva fila, %FOUND false en caso contrario. devuelve true si el ltimo FETCH no devolvi una nueva fila, se %NOTFOUND utiliza frecuentemente para salir de bucles. %ISOPEN Devuelve verdadero si el cursor est abierto. Devuelve el n de filas extradas hasta el momento.
%ROWCOUNT
51
OL-ORACLE02T
PL/ SQL
Mdulo 2
Bucles de cursores
Puesto que se trata de conjunto de filas se necesita un bucle para procesar las filas: tenemos que leer una fila tratarla, leer otra, tratarla, ect.. Existen tres tipos:
LOOP Bsico WHILE (requiere una lectura previa) FOR, es un atajo para procesar cursores, ya que implcitamente lo abre, trabaja con l, sale y lo cierra. El registro est declarado de manera implcita.
52
OL-ORACLE02T
PL/ SQL
Mdulo 2
BUCLE LOOP
DECLARE --Primero declaramos el cursor. CURSOR C1 IS SELECT.. VAR_CI C1%ROWTYPE; --Defino la variable para guardar los datos del cursor BEGIN OPEN CI; --Abrimos el cursor LOOP --Leemos con el cursor la primera fila y la guardamos en la variable. FETCH C1 INTO VAR_CI; -- salir si no hay datos EXIT WHEN C1%NOTFOUND; --tambin es posible: [IF C1%NOFOUND THEN EXIT; END IF:] .... --tratamiento de filas END LOOP; --Cerramos el cursor CLOSE CI; ..
53
OL-ORACLE02T
PL/ SQL
Mdulo 2
DECLARE --LA PARTE DECLARATIVA ES IGUAL AL OTRO TIPO DE BUCLE CURSOR C1 IS SELECT.. VAR_CI C1%ROWTYPE; --Defino la variable para guardar los datos del cursor BEGIN OPEN CI; --Abrimos el cursor --Leemos con el cursor la primera fila y la guardamos en la variable. FETCH C1 INTO VAR_CI; --Mientras encuentres datos se trabaja WHILE C1%FOUND LOOP --tratamiento de filas --Antes de salir volvemos a leer. FETCH C1 INTO VAR_CI; END LOOP;
54
OL-ORACLE02T
PL/ SQL
Mdulo 2
BUCLE FOR
En el bucle for, no se declara la variable de cursor. No se abre si se cierra, no se hace un FETCH, est implicito. No se comprueba si se ha llegado al final de los datos. Es el ms cmodo de los tres, pero no siemptre se puede utilizar.
DECLARE --LA PARTE DECLARATIVA ES IGUAL AL OTRO TIPO DE BUCLE CURSOR C1 IS SELECT.. BEGIN FOR V_C1 IN C1 LOOP .. END LOOP; ..
55
OL-ORACLE02T
PL/ SQL
Mdulo 2
FOR Loops con Subconsultas No es necesario declarar el cursor BEGIN FOR emp_record IN (SELECT apellido, departamento FROM empleados) LOOP -- Implcitamente se abre y carga IF emp_record.departmento = 80 THEN ...... END LOOP; -- se produce el cierre implcito END;
56
OL-ORACLE02T
PL/ SQL
Mdulo 2
Cursores Avanzados
Cursores con parmetros A los cursores se les pueden pasar parmetros en el momento de su apertura, de manera que se puedan abrir con distintos datos segn los parmetros pasados en diferentes aperturas. Es un cursor variable, cuya clusula where no es siempre la misma depende del valor de un parmetro. Se puede abrir y cerrar las veces que queramos, y cada vez con valores distintos. Se puede utilizar con parmetros y con variables en la clusula where. Ningn parmetro debe tener longitud ni precisin.
57
OL-ORACLE02T
PL/ SQL
Mdulo 2
Ejemplo: Realizamos un tratamiento distinto para los empleados que ganen 1000 y otro diferente para los que ganen 5000. Primero lo abrimos y realizamos la primera operacin, cerramos y realizamos la segunda operacin. DECLARE CURSOR C1(PARAMETRO1 NUMBER) IS SELECT * FROM EMP WHERE SAL < PARAMETRO1; BEGIN OPEN C1(1000); . CLOSE C1; OPEN C1(5000); CLOSE C1; .
Con un bucle for, ni se abre ni se cierra, y sera: FOR V_C1 IN C1(3000) LOOP
58
OL-ORACLE02T
PL/ SQL
Mdulo 2
59
OL-ORACLE02T
PL/ SQL
Mdulo 2
Ejemplos: Listar a los empleados de la tabla emp que sean analistas 1) Con bucle loop
DECLARE CURSOR C1 IS SELECT ENAME,SAL,JOB FROM EMP WHERE JOB='ANALYST'; VAR_CI C1%ROWTYPE; BEGIN OPEN C1; LOOP FETCH C1 INTO VAR_CI; DBMS_OUTPUT.PUT_LINE('ANALISTAS:' || VAR_CI. ENAME); EXIT WHEN C1%NOTFOUND; END LOOP; CLOSE C1; END; /
60
OL-ORACLE02T
PL/ SQL
Mdulo 2
VAR_CI C1%ROWTYPE; BEGIN OPEN C1; FETCH C1 INTO VAR_CI; WHILE C1%FOUND LOOP DBMS_OUTPUT.PUT_LINE('ANALISTAS:' || VAR_CI.ENAME); FETCH C1 INTO VAR_CI; END LOOP; CLOSE C1; END; /
61
OL-ORACLE02T
PL/ SQL
Mdulo 2
DECLARE CURSOR C1 IS SELECT ENAME,SAL,JOB FROM EMP WHERE JOB='ANALYST'; BEGIN FOR VAR_C1 IN C1 LOOP DBMS_OUTPUT.PUT_LINE('ANALISTAS:' || VAR_C1.ENAME); END LOOP; END; /
62
OL-ORACLE02T
PL/ SQL
Mdulo 2
Gestin de Excepciones
Manejando Excepciones Una excepcin es un identificador que se lanza durante la ejecucin. Se utilizan para controlar errores en tiempo de ejecucin. Si no se contemplan y la situacin de error se produce el programa falla. Existen las predefinidas por Oracle y las definidas por el programador. Hablaremos tambin de RAISE_APPLICATION_ERROR. Se lanzan:
Al producirse un error en tiempo de ejecucin (de manera implcita). Al lanzarse explcitamente (por el programador).
Para manejarla se puede: Atraparla con un manejador, contemplarla en el programa. Propagarla al bloque superior.
63
OL-ORACLE02T
PL/ SQL
Mdulo 2
Caractersticas.
Excepciones predefinidas : estn recogidas en el paquete STANDARD as NO_DATA_FOUND, TOO_MANY_ROWS, ZERO_DIVIDE, INVALID_CURSOR etc. Excepciones definidas por el programador : se deben declarar explcitamente en la seccin DECLARE. Las excepciones se pueden producir en cualquier parte del programa. Slo se pueden tratar de manera adecuada en la parte de tratamiento de excepciones. El mbito es el del bloque en la que se produzcan.
64
OL-ORACLE02T
PL/ SQL
Mdulo 2
Generacin Las excepciones predefinidas se elevan de forma automtica en el momento de producirse. Se paraliza la ejecucin y busca algn gestor de excepciones, aplicndolo o concluyendo la ejecucin en caso que no lo haya. Tratamiento Se tratan en el bloque EXCEPTION que puede contener un conjunto de gestores, cada uno orientado a una excepcin. EXCEPTION WHEN NO_DATA_FOUND THEN <sentencias> - - Gestor 1 WHEN mi_excepcion THEN <sentencias> - - Gestor 2 WHEN OTHERS THEN <sentencias> - - Gestor 3, en este caso el gestor por defecto. END;
Ejemplo excepciones del programador: Caractersticas: -Se deben de declarar, porque es algo que se define el programador. -Estn en la parte ejecutable del programa. -Se tratan en el bloque de excepciones.
65
OL-ORACLE02T
Ejemplo:
PL/ SQL
Mdulo 2
Bloque PL para comprobar si existen nombres nulos en la tabla EMP. DECLARE CURSOR CUR1 IS SELECT ENAME,JOB,EMPNO FROM EMP; NOMBRE_NULO EXCEPTION; NUM_EMP EMP.EMPNO%TYPE; BEGIN FOR X IN CUR1 LOOP IF X.ENAME IS NULL THEN NUM_EMP :=X.EMPNO; --ROMPE EL FLUJO DEL PROGRAMA, SE VA A BUSCAR LA EXCEPCIN A LA --ZONA DE EXCEPCIONES RAISE NOMBRE_NULO; END IF; DBMS_OUTPUT.PUT_LINE('EMPLEADO NUMERO: ' || X.EMPNO); END LOOP; EXCEPTION WHEN NOMBRE_NULO THEN DBMS_OUTPUT.PUT_LINE('EMPLEADO NUMERO' || NUM_EMP || 'TIENE EL NOMBRE A NULOS '); --ES NECESARIO VOLCAR EL NOMBRE EN UNA VARIABLE NUM_EMP PORQUE --AL SALIR DEL BUCLE DEL CURSOR LA VARIABLE X PIERDE SU VALOR Y SU MBITO END; /
66
OL-ORACLE02T
PL/ SQL
Mdulo 2
Excepciones de Oracle.
Son las predefinidas por Oracle. Las diferencia con las anteriores:
No se declaran, el motor de la base de datos las conoce. No se lanzan con Raise, el programa detecta la condicin de error
CURSOR_ALREADY_OPEN, si est ya abierto el cursor. DUP_VAL_ON_INDEX, valor duplicado en ndice, intentar insertar una fila duplicada en una columna indexada con un ndice nico. INVALID_CURSOR, ejecutar una operacin con un cursor cerrado. INVALID_NUMBER, se intenta convertir una cadena de caracteres a un numero. LOGON_DENIED, conexin a Oracle denegada, porque usuario o contrasea son incorrectos. NO_DATA_FOUND, Ejecutar una sentencia select que no devuelve ninguna fila, ejemplo: busco al empleado que gana ms de 6000 euros al mes. TOO_MANY_ROWS, Ejecutar una select que devuelve ms de una fila, buscar a los empleados que ganan entre 1000 y 1500 euros al mes.
67
OL-ORACLE02T
PL/ SQL
Mdulo 2
NOT_LOGED_ON, acceder a la base de datos sin haber iniciado la sesin. STORAGE_ERROR, pl se queda sin memoria ejecutando una sentencia. TIMEOUT_ON_RESOURCE, se acaba el tiempo de espera para un determinado recurso. TRANSACTION_BACKED_OUT, una transaccin por el motivo que sea no se completa. VALUE_ERROR, error aritmtico de conversin o de truncado. ZERO_DIVIDE, cuando se intenta dividir por cero.
68
OL-ORACLE02T
PL/ SQL
Mdulo 2
Ejemplo Pedir dos nmeros por pantalla para realizar una divisin. Se contempla que el divisor pueda ser 0. DECLARE --EJEMPLO DE EXCEPCION PREDEFINIDA POR ORACLE(ZERO DIVIDE) NUM1 NUMBER(2):=&NUMERO1; NUM2 NUMBER(2):=&NUMERO2; RESUL NUMBER(5,2);
BEGIN RESUL :=NUM1/NUM2; DBMS_OUTPUT.PUT_LINE('NUM1/NUM2 = ' || RESUL); EXCEPTION WHEN ZERO_DIVIDE THEN DBMS_OUTPUT.PUT_LINE('IMPOSIBLE DIVIDIR POR 0'); END; /
69
OL-ORACLE02T
PL/ SQL
Mdulo 2
WHEN OTHERS
Existen ocasiones donde no nos interesar contemplar las excepciones una a una. Para ello existe una excepcin genrica OTHERS donde el programa bifurca cuando se produzca una condicin de error. Ejemplo: EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('SE HA PRODUCIDO UN ERROR');
SQLCODE, SQLERRM
Es posible saber en que acceso se ha producido el error, y tambin podemos saber el cdigo y el mensaje de error, accediendo a las variables: SQLCODE SQLERRM Cada error tiene su cdigo interno y su texto de error.
70
OL-ORACLE02T
PL/ SQL
Mdulo 2
Ejemplo: Repitamos el anterior pero utilizando la excepcin genrica WHEN OTHERS. DECLARE V_NOMBRE EMP.ENAME%TYPE; V_EMPNO EMP.EMPNO%TYPE:=&EMPNO; V_CODIGO NUMBER; V_MENSAJE VARCHAR2(60); BEGIN SELECT ENAME INTO V_NOMBRE FROM EMP WHERE EMPNO=V_EMPNO; DBMS_OUTPUT.PUT_LINE('NOMBRE: ' || V_NOMBRE); EXCEPTION WHEN OTHERS THEN V_CODIGO:=SQLCODE; V_MENSAJE:=SUBSTR(SQLERRM,1,60); DBMS_OUTPUT.PUT_LINE('SE HA PRODUCIDO UN ERROR' || V_CODIGO || ' '|| V_MENSAJE); END; /
71
OL-ORACLE02T
Propagacin
PL/ SQL
Mdulo 2
Si se produce una excepcin en un bloque interno y no es tratada en l, se transmite al bloque inmediatamente superior para su tratamiento.
RAISE_APPLICATION_ERROR
Este procedimiento se puede utilizar para propagar mensajes de error personalizados desde subprogramas almacenados. Tiene como caracterstica que para la ejecucin del programa all donde sea invocado. Tiene dos argumentos: un cdigo que va desde -20000 hasta -20999 y un texto de error. Las usaremos mas adelante en triggers. Ejemplo: BEGIN DELETE FROM EMP WHERE EMPNO= &NUMERO; IF SQL%NOTFOUND THEN RAISE_APPLICATION_ERROR (-20300, EL EMPLEADO NO EXISTE); END IF; END; /
72
OL-ORACLE02T
PL/ SQL
Mdulo 2
Subprogramas
Un subprograma es un bloque PL / SQL nominado, que puede aceptar parmetros y ser invocado desde un entorno llamante. Provee modularidad (al estar basado en bloques PL / SQL), reusabilidad (al ser almacenable) y facilidad de mantenimiento. Tipos:
Procedimientos, que realizan una accin. Funciones, que computan y devuelven un solo valor. Paquetes, conjunto de procedimientos y funciones (admiten otros objetos) Triggers, son especiales porque estn asociados a una tabla y a una accin sobre esa tabla.
73
OL-ORACLE02T
PL/ SQL
Mdulo 2
Funciones
Una funcin es un bloque nominado PL / SQL que devuelve un valor. Una funcin puede ser almacenada en una base de datos como un objeto para su reutilizacin continuada. Si la funcin est almacenada se denomina global y puede ser compartida por otros usuarios de la base de datos. Si no est almacenada se llama local y entonces forma parte de otra unidad de programacin pero no es independiente. Veremos un ejemplo ms adelante. Una funcin es llamada como parte de una expresin. Sintaxis de Creacin Funcin Global CREATE [OR REPLACE] FUNCTION nombre [(parametro1 [MODO] tipo, parametro2 [MODO] tipo,....)] RETURN tipo tipo de dato del valor devuelto IS | AS equivalente a DECLARE en un pl annimo Bloque PL/SQL; Existen en general, 3 tipos de parmetros: IN (entrada), OUT (salida), INOUT(entrada/salida) Puesto que las funciones devuelven valores a travs de la clusula RETURN slo . deberan declararse parmetros IN El bloque PL / SQL debe contener al menos una sentencia RETURN. Tras compilar SHOW ERRORS mostrara posibles errores de compilacin.
74
OL-ORACLE02T
PL/ SQL
Mdulo 2
Ejemplo: CREATE OR REPLACE FUNCTION obten_sueldo (p_id IN empl.empno%TYPE) RETURN NUMBER IS v_sueldo emp.sal%TYPE : = 0; BEGIN SELECT sal INTO v_sueldo FROM empl WHERE empno = p_id; RETURN v_sueldo; END obten_sueldo; /
75
OL-ORACLE02T
PL/ SQL
Mdulo 2
Ejecucin
Las funciones se invocan como parte de una expresin PL / SQL. Se debe crear una variable para recoger el valor devuelto por la funcin. Ejemplos de llamada: 1) A travs de la tabla dual: SQL> SELECT OBTEN_SUELDO(7902) FROM DUAL; devuelve el resultado por pantalla
2) Dentro de otro programa pl: DECLARE CUANTO_GANA NUMBER; BEGIN CUANTO_GANA:= OBTEN_SUELDO(&NUMERO_EMP); DBMS_OUTPUT.PUT_LINE(GANA || CUANTO_GANA); END; /
76
OL-ORACLE02T
PL/ SQL
Mdulo 2
Restricciones en el Uso
Para poder ser invocadas desde expresiones SQL, una funcin definida por el usuario debe:
Ser una funcin almacenada. Aceptar nicamente parmetros IN. Aceptar nicamente tipos de datos vlidos para SQL, no tipos especficos de PL / SQL como son los parmetros. Devolver tipos de datos vlidos para SQL. Funciones llamadas desde sentencias UPDATE / DELETE en una tabla T no pueden contener DML, ni hacer consultas sobre la misma tabla T. Las funciones llamadas no pueden contener sentencias que finalicen las transacciones. Llamadas a subprogramas que contravengan estas limitaciones provocaran excepciones.
77
OL-ORACLE02T
PL/ SQL
Mdulo 2
Ejemplo: CREATE OR REPLACE FUNCTION va_dar_error (p_sal NUMBER) RETURN NUMBER IS BEGIN INSERT INTO empleados (nuempl, apellido, feching, nombre) VALUES (00120, Perez,14-NOV-2001, Jose); RETURN (p_sal + 100); END va_dar_error; / UPDATE empleados SET salar = va_dar_error(12300) WHERE nuempl = 00152; ERROR at line 1 ORA-04091 table EMPLEADOS is mutating....
78
OL-ORACLE02T
PL/ SQL
Mdulo 2
Eliminacin
Para borrar una funcin de la base de datos: Sintaxis: DROP FUNCTION nombre_funcion Ejemplo: DROP FUNCTION va_dar_error;
79
OL-ORACLE02T
PL/ SQL
Mdulo 2
Funciones locales
Ejemplo: FUNCTION SUMAR (N1 IN NUMBER,N2 IN NUMBER) RETURN NUMBER IS -- ESTE IS ES COMO EL DECLARE DE UN BLOQUE PL, ES DECIR, DEBAJO DE -- EL Y ANTES DEL BEGIN VAN LAS VARIABLES DEL BLOQUE V_RESUL NUMBER(4); BEGIN V_RESUL := N1+N2; RETURN (V_RESUL); -- PODRIA SER TAMBIEN, RETURN N1+N2 END SUMAR; /
80
OL-ORACLE02T
PL/ SQL
Mdulo 2
Ejecucin: Con un bloque pl. Recordar que no est almacenada en la bd, est dentro de otro programa! DECLARE NUM1 NUMBER(2):=&NUMERO1; NUM2 NUMBER(2):=&NUMERO2; V_RESULTADO NUMBER (4); FUNCTION SUMAR (N1 IN NUMBER,N2 IN NUMBER) RETURN NUMBER IS V_RESUL NUMBER(4); BEGIN V_RESUL := N1+N2; RETURN (V_RESUL); -- PODRIA SER TAMBIEN, RETURN N1+N2 END SUMAR;
81
OL-ORACLE02T
PL/ SQL
Mdulo 2
Procedimientos
Un procedimiento es un bloque nominado PL / SQL que puede devolver de 0 a n valores. Un procedimiento puede ser almacenado en una base de datos como un objeto para su reutilizacin continuada. Si est almacenado se denomina global y puede ser compartido por otros usuarios de la base de datos. Si no est almacenado se llama local y entonces forma parte de otra unidad de programacin pero no es independiente. Veremos un ejemplo ms adelante.
82
OL-ORACLE02T
PL/ SQL
Mdulo 2
Parmetros OUT
CREATE PROCEDURE cuadrado_cubo (p_numero IN NUMBER , p_cuadrado OUT NUMBER, p_cubo OUT NUMBER) IS BEGIN p_cuadrado : = p_numero* p_numero; p_cubo : = p_cuadrado * p_numero; END cuadrado_cubo; /
Sin parmetros
CREATE OR REPLACE PROCEDURE poner_departamentos (p_nombre IN departamentos.nomdep%TYPE DEFAULT Innominioso, p_numero IN departamentos.numdep%TYPE DEFAULT A01) IS BEGIN INSERT INTO departamentos (NUMDEP,NOMDEP) VALUES (p_numero, p_nombre); END poner_departamentos; /
83
OL-ORACLE02T
PL/ SQL
Mdulo 2
Llamadas:
1) Desde bloques annimos BEGIN SUBIR_SALARIO(&NUMEMP,&SALARIO); ....... END; 2) Desde sql*plus: SQL> EXECUTE SUBIR_SALARIO(7902, 200);
84
OL-ORACLE02T
PL/ SQL
Mdulo 2
Procedimientos locales
Ejemplo: DECLARE NUM1 NUMBER(2) := &NUMERO1;
NUM2 NUMBER(2) := &NUMERO2; V_RESUL NUMBER(4); PROCEDURE MULTIPLICAR (N1 IN NUMBER, N2 IN NUMBER,N3 OUT NUMBER) IS BEGIN N3:= N1 * N2; END MULTIPLICAR; BEGIN MULTIPLICAR(NUM1,NUM2,V_RESUL); DBMS_OUTPUT.PUT_LINE('EL RESULTADO ES ' || V_RESUL); END; / Es similar a lo dicho en funciones.
85
OL-ORACLE02T
PL/ SQL
Mdulo 2
86
OL-ORACLE02T
PL/ SQL
Mdulo 2
Paquetes
Agrupan lgicamente subprogramas, tipos PL / SQL y elementos que son homogneos. Consiste en dos partes:
A diferencia de los procedimientos y funciones, los paquetes no pueden estar contenidos dentro de un bloque local, slo se pueden almacenar en la base de datos. Se compilan y se almacenan por separado. La especificacin de un paquete puede existir sin su cuerpo, pero lo contrario es imposible.
Sintaxis de la cabecera
CREATE [OR REPLACE] PACKAGE nombre IS | AS declaraciones de elementos y tipos especificacin de subprogramas END nombre; Las variables declaradas en la especificacin del paquete se inicializan como NULL por defecto. Todos los elementos declarados en el paquete son visibles a los usuarios con los privilegios concedidos para ello.
87
OL-ORACLE02T
PL/ SQL
Mdulo 2
Ejemplo: Parte declarativa de un paquete CREATE OR REPLACE PACKAGE EJEMPLO_PAQ IS PROCEDURE MULTIPLICAR (N1 IN NUMBER, N2 IN NUMBER); FUNCTION SUMAR(N1 IN NUMBER,N2 IN NUMBER) RETURN NUMBER; END EJEMPLO_PAQ;
Parte ejecutable de un paquete CREATE OR REPLACE PACKAGE BODY EJEMPLO_PAQ IS FUNCTION SUMAR(N1 IN NUMBER,N2 IN NUMBER) RETURN NUMBER IS V_RESUL NUMBER(4);
BEGIN V_RESUL := N1+N2 RETURN (V_RESUL); END SUMAR; PROCEDURE MULTIPLICAR (N1 IN NUMBER, N2 IN NUMBER,N3 OUT NUMBER) IS BEGIN N3:= N1 * N2; END MULTIPLICAR; END EJEMPLO_PAQ;
88
OL-ORACLE02T
PL/ SQL
Mdulo 2
89
OL-ORACLE02T
PL/ SQL
Mdulo 2
Eliminacin Para eliminar tanto el cuerpo como la especificacin: DROP PACKAGE mi_paquete; Para eliminar slo el cuerpo: DROP PACKAGE BODY mi_paquete;
90
OL-ORACLE02T
PL/ SQL
Mdulo 2
Triggers
En esta seccin veremos triggers que son bloques o procedimientos PL / SQL asociados a una tabla. Se disparan al producirse un evento (sentencia DML) sobre una tabla. Se asemejan con los procedimientos y funciones en que son bloques PL/SQL nominados con secciones declarativa, ejecutable y de manejo de excepciones y en que se almacenan en la base de datos. Se diferencian en que se ejecutan implcitamente cuando se ejecuta una sentencia de manipulacin de datos sobre una tabla (INSERT, UPDATE, DELETE), y en que el disparador no admite argumentos. Existen otros tipos de triggers que no sern vistos en esta seccin.
91
OL-ORACLE02T
PL/ SQL
Mdulo 2
Uso de Triggers
Los disparadores se utilizan principalmente para:
Para el mantenimiento de restricciones de integridad complejas, que no sean posibles con las restricciones declarativas definidas en el momento de crear la tabla. En auditora de la informacin contenida en la tabla, registrando los cambios realizados y la identidad de quien lo llev a cabo. El aviso automtico a otros programas de que hay que llevar a cabo una determinada accin, cuando se realiza un cambio en la tabla.
92
OL-ORACLE02T
PL/ SQL
Mdulo 2
BEFORE: se ejecuta antes que el evento DML que ha lo ha lanzado. AFTER: se ejecuta despus que el evento que lo origina. INSTEAD OF; se ejecuta el cuerpo del trigger en vez de la sentencia que lo lanza. Se emplea en vistas que no son modificables de otra manera. No es muy comn.
93
OL-ORACLE02T
PL/ SQL
Mdulo 2
Tipos de trigger
La tipologa depende de la frecuencia con la que queremos que se ejecute, as:
A nivel de sentencia: el cuerpo del trigger se ejecuta una nica vez al producirse el evento. Es el por defecto. Se dispara aunque no haya filas afectadas. A nivel de fila: el cuerpo se ejecuta una vez por cada fila afectada por el evento, no se dispara si el evento no afecta a fila alguna.
Secuencia de disparo
En caso de concurrencia de eventos, la secuencia de disparo los triggers, sera:
RESTRICCIONES
BEFORE statement trigger BEFORE row trigger (n veces) AFTER row trigger (n veces) AFTER Statement trigger
COMMIT, ROLLBACK, SAVEPOINT. No pueden realizar modificaciones de datos (INSERT, UPDATE, DELETE) sobre una tabla mutante (aquella que est siendo modificada por la instruccin que dispar el TRIGGER).
94
OL-ORACLE02T
PL/ SQL
Mdulo 2
Condicin de tiempo : BEFORE, AFTER Un evento: INSERT, UPDATE o DELETE. Una tabla: ON nombre_tabla | nombre_vista. Un tipo: sentencia o fila. Una clasula WHEN : condicin restrictiva. El cuerpo del trigger. CREATE [OR REPLACE] TRIGGER nombre timing event1 [OR event2] [OR event3] ON nombre_tabla trigger_body
Los nombres de los triggers deben ser nicos con respecto a otros triggers del mismo esquema.
95
OL-ORACLE02T
PL/ SQL
Mdulo 2
Ejemplos: Disparador de sentencia: CREATE OR REPLACE TRIGGER EJEMPLO1 AFTER INSERT ON DEPT BEGIN -- DISPARADOR DE SENTENCIA DBMS_OUTPUT.PUT_LINE('SE HA INSERTADO UN REGISTRO'); END; / Disparador de fila: OLD y NEW En un trigger a nivel de fila, se puede referenciar el valor de una columna antes y despus del cambio de datos. CREATE OR REPLACE TRIGGER EJEMPLO2 BEFORE UPDATE ON DEPT FOR EACH ROW BEGIN DBMS_OUTPUT.PUT_LINE('SE SUSTITUIRA LA SIGUIENTE FILA: '); DBMS_OUTPUT.PUT_LINE(:OLD.DEPTNO || ' ' || :OLD.DNAME ||' '|| :OLD.LOC); DBMS_OUTPUT.PUT_LINE('POR ESTA OTRA:'); DBMS_OUTPUT.PUT_LINE(:NEW.DEPTNO ||' '||:NEW.DNAME||' '||:NEW.LOC); END; / --DISPARADOR DE FILA
96
OL-ORACLE02T
PL/ SQL
Mdulo 2
97
OL-ORACLE02T
PL/ SQL
Mdulo 2
Gestin de Triggers
Al crearse un TRIGGER se activa, se puede desactivar con la orden: SQL> ALTER TRIGGER Vigila DISABLE; Se puede volver a activar: SQL> ALTER TRIGGER Vigila ENABLE; La tabla USER_TRIGGERS es til para conseguir informacin sobre los disparadores. SQL> SELECT TRIGGER_NAME, TRIGGER_TYPE , TRIGGERING_EVENT FROM USER_TRIGGER;
Borrado La clasula DROP permite eliminar un trigger de la base de datos: DROP TRIGGER Vigila;
98
OL-ORACLE02T
PL/ SQL
Mdulo 2
Ms acerca de triggers
Integridad de los datos con triggers Los triggers pueden complementar las herramientas propias del sistema, dando valores por defecto, implementando chequeos adicionales,... 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,No bajar el salario); END;
99