DAI PLSQL

55

Click here to load reader

Transcript of DAI PLSQL

Page 1: DAI PLSQL

PROGRAMACIÓN EN L4G Y HERRAMIENTAS CASE

TEMA 12: INTRODUCCIÓN AL LENGUAJE PL/SQL

1. INTRODUCCIÓN2. CARACTERÍSTICAS DEL LENGUAJE

2.1. BLOQUES PL / SQL 2.2. DEFINICIÓN DE DATOS COMPATIBLES CON PL / SQL 2.3. ESTRUCTURAS DE CONTROL2.4. SOPORTE PARA ÓRDENES DE MANIPULACIÓN DE DATOS2.5. USO DE CURSORES2.6. GESTIÓN DE EXCEPCIONES2.7. ESTRUCTURA MODULAR

3. INTERACCIÓN CON EL USUARIO EN PL / SQL 4. USO Y EJEMPLOS DE BLOQUES ANÓNIMOS Y PROCEDIMIENTOS

4.1. BLOQUES ANÓNIMOS4.2. USO DE PROCEDIMIENTOS

Page 2: DAI PLSQL

TEMA 12: INTRODUCCIÓN AL LENGUAJE PL/SQL

Oracle Incorpora un gestor PL/SQL en el servidor de la BD y en las principales herramientas (FORMS, REPORTS, GRAPHICS,…). Este lenguaje basado en el lenguaje ADA, incorpora todas las características propias de los lenguajes de 3ª generación: manejo de variables, estructura modular (procedimientos y funciones), estructuras de control (bifurcaciones, bucles y demás estructuras), control de excepciones, así como una total integración en el entorno Oracle.Los programas creados con PL/SQL se pueden almacenar en la BD como cualquier otro objeto de ésta.

1. Introducción

Page 3: DAI PLSQL

TEMA 12: INTRODUCCIÓN AL LENGUAJE PL/SQL

PL/SQL es un lenguaje procedimental diseñado por Oracle para trabajar con la BD. Está incluido en el servidor y en algunas herramientas de cliente.Soporta todos los comandos de consulta y manipulación de datos, aportando al lenguaje SQL las estructuras de control y otros elementos propios de los lenguajes procedimentales de 3ª generación. Su unidad de trabajo es el bloque, constituido por un conjunto de declaraciones, instrucciones y mecanismos de gestión de errores y excepciones.

2. Características del lenguaje

Page 4: DAI PLSQL

TEMA 12: INTRODUCCIÓN AL LENGUAJE PL/SQL

Con PL/SQL se pueden construir distintos tipos de programas: procedimientos, funciones y bloques anónimos, paquetes,…; todos ellos tienen en común una estructura básica característica del lenguaje denominada Bloque.Un bloque tiene 3 zonas:

• Zona de declaraciones: donde se declaran objetos (variables, constantes,…) locales. Suele ir precedida por la cláusula DECLARE (o IS o AS en los procedimientos y funciones). Es opcional.

• Un conjunto de instrucciones precedido por la cláusula BEGIN.• Una zona de tratamiento de excepciones precedido por la cláusula EXCEPTION. Esta

zona, igual que la de declaraciones, es opcional.

El formato genérico del bloque es:[ DECLARE

<declaraciones> ]BEGIN

<instrucciones>[ EXCEPTION

<gestión de excepciones> ]END;/* La zona de declaraciones comenzará con DECLARE o con IS dependiendo del tipo de

bloque. Las únicas cláusulas obligatorias son BEGIN y END */

2.1. Bloques PL / SQL

Page 5: DAI PLSQL

TEMA 12: INTRODUCCIÓN AL LENGUAJE PL/SQL

Ejemplo: Borrar el departamento número 20, pero antes se crea un departamento provisional, al que se asigna los empleados del departamento 20 que de otra forma hubieran sido borrados al borrar el departamento. También informa del número de empleados afectados.

DECLAREv_num_emple NUMBER(2);

BEGININSERT INTO Depart VALUES (99,’PROVISIONAL’,NULL);

UPDATE Emple SET DEPT_NO=99 WHERE DEPT_NO=20;v_num_emple := SQL%ROWCOUNT;DELETE FROM DEPART WHERE DEPT_NO=20;DBMS_OUTPUT.PUT_LINE (v_num_emple || ‘ Empleados ubicados en PROVISIONAL’);EXCEPTION

WHEN OTHERS THEN ROLLBACK;RAISE_APPLICATION_ERROR (-20000, ‘Error en la aplicación’);

END;

2.1. Bloques PL / SQL

Page 6: DAI PLSQL

TEMA 12: INTRODUCCIÓN AL LENGUAJE PL/SQL

PL/SQL dispone de tipos de datos compatibles con los tipos utilizados para las columnas de las tablas: NUMBER, VARCHAR2, DATE,… además de otros propios como BOOLEAN. Las declaraciones de los datos deben realizarse en la sección de declaraciones:Ejemplo:DECLAREImporte NUMBER(8,2);Contador NUMBER(2) DEFAULT 0;Nombre CHAR(20); NOT NULL := ‘MIGUEL’;Nuevo VARCHAR2(15);BEGIN…

PL/SQL permite declarar una variable del mismo tipo que otra variable o que una columna de una tabla mediante el atributo %TYPE.

Ejemplo: Declara la variable NombreActual que es del mismo tipo que la columna Nombre de la tabla Empleados. NombreActual Empleados.Nombre%TYPE;

También se puede declarar una variable para guardar una fila completa de una tabla mediante el atributo %ROWTYPE.

Ejemplo: Declara la variable MiFila, que es del mismo tipo que las filas de la tabla Empleados.MiFila Empleados%ROWTYPE;

2.2. Definición de datos compatibles con PL / SQL

Page 7: DAI PLSQL

TEMA 12: INTRODUCCIÓN AL LENGUAJE PL/SQL

2.3.1. Estructuras de control alternativas

2.3.2. Estructuras de control repetitivas

2.3. Estructuras de control

IF <condición> THENinstrucciones;…ELSIF <condición2> THENInstrucciones;…ELSIF <condición3> THENInstrucciones;…ELSEInstrucciones;…END IF;

IF <condición> THENinstrucciones;…ELSEInstrucciones;…END IF;

IF <condición> THENinstrucciones;…END IF;

Alternativa múltipleAlternativa dobleAlternativa simple

LOOPinstrucciones;…EXIT WHEN <condición>Instrucciones…END LOOP;

FOR <variable> IN <mínimo> . . <máximo> LOOPinstrucciones;…END LOOP;

WHILE <condición> LOOPinstrucciones;…END LOOP;

Iterar… fin iterar salir si…Para Mientras

Page 8: DAI PLSQL

TEMA 12: INTRODUCCIÓN AL LENGUAJE PL/SQL

Desde PL/SQL se puede ejecutar cualquier orden de manipulación de datos.

Ejemplo: Borra de la tabla Clientes la fila correspondiente al cliente cuyo NIF se especifica en la variable vnif: DELETE FROM clientes WHERE nif = vnif;

Ejemplo: Actualiza en la tabla Clientes la columna Stock, correspondiente al código de producto especificado en la variable VCodigo, restándoles el valor que se especifica en la variable UnidadesVendidas.UPDATE Productos SET Stock:=Stock –UnidadesVendidas WHERE CodProd = VCodigo;

Ejemplo: Añade a la tabla Clientes una fila con los valores contenidos en las variables que se especifican:INSERT INTO Clientes VALUES (VNum, VNomb, VLoc);

2.4.Soporte para órdenes de manipulación de datos

Page 9: DAI PLSQL

TEMA 12: INTRODUCCIÓN AL LENGUAJE PL/SQL

En PL/SQL el resultado de una consulta no va directamente al Terminal del usuario, sino que se guarda en un área de memoria a la que se accede mediante una estructura denominada cursor. Los cursores sirven para guardar el resultado de una consulta.

Ejemplo: Para guardar el resultado de la siguiente consulta en la variable VNumVentas, que deberáhaber sido declarada previamente, emplearemos:SELECT COUNT(*) INTO VNumVentas FROM Ventas;

El formato básico es: SELECT <columna/s> INTO <variable/s> FROM <TABLA> [ where … ]La/s variable/s que siguen al INTO reciben el valor de la consulta. Por tanto, debe haber coincidencia en el tipo con las columnas especificadas en la cláusula SELECT.

Ejemplo: Para guardar el resultado de la siguiente consulta en la variable VNumVentas, que deberáhaber sido declarada previamente, emplearemos:DECLAREvApe VARCHAR2(10);vOficio VARCHAR2(10);BEGINSELECT apellido, oficio INTO vApe, vOficio FROM Emple WHERE emp_no=7900;DBMS_OUTPUT.PUT_LINE (vApe || ¡ -‘ || vOficio);END;

2.5. Uso de Cursores

Page 10: DAI PLSQL

TEMA 12: INTRODUCCIÓN AL LENGUAJE PL/SQL

Ejemplo anterior con tratamiento de excepciones: DECLAREvApe VARCHAR2(10);vOficio VARCHAR2(10);BEGINSELECT apellido, oficio INTO vApe, vOficio FROM Emple WHERE emp_no=7900;DBMS_OUTPUT.PUT_LINE (vApe || ‘-‘ || vOficio);

EXCEPTIONWHEN NO_DATA FOUND THEN insert into Temp values (‘Noy hay datos’);WHEN TOO_MANY_ROWS THEN insert into Temp values (‘Demasiadosdatos);WHEN OTHERS THEN RAISE_APPLICATION_ERROR (-20000, ‘Error en aplicación’);END;

Si PL/SQL detecta una excepción, pasa el control a la cláusula WHENcorrespondiente de la sección EXCEPTION del bloque que lo tratará según lo establecido. Al finalizar este tratamiento, se devuelve el control al programa que llamó al bloque que trató la excepción.

2.6. Gestión de excepciones

Page 11: DAI PLSQL

TEMA 12: INTRODUCCIÓN AL LENGUAJE PL/SQL

En esta aproximación inicial podemos distinguir los siguientes tipos de programas:• Bloques anónimos: No tienen nombre. La zona de declaraciones comienza con la palabra DECLARE. Su utilización real es escasa.• Subprogramas: Son bloques PL/SQL que tienen un nombre. La zona de declaraciones comienza con la palabra IS. A su vez, pueden ser de 2 tipos:

Procedimientos: es el tipo de programas más usado en PL/SQL. Normalmente se almacenan en la BD. Su formato es:PROCEDURE <nombre procedimiento>[ ( <lista de parámetros> ) ]IS

[ <declaraciones> ]BEGIN

<instrucciones>;[ EXCEPTION

< excepciones> ; ]END;Se pueden distinguir 2 partes en el procedimiento: la cabecera, que es donde va el nombre del procedimiento y los parámetros; y el cuerpo del procedimiento que es un bloque PL/SQL.

Funciones: Su formato genérico es similar al de los procedimientos, pero éstas pueden devolver un valor.

2.7. Estructura modular

Page 12: DAI PLSQL

TEMA 12: INTRODUCCIÓN AL LENGUAJE PL/SQL

PL/SQL no es un lenguaje para interactuar con el usuario, sino para trabajar con la BD. Por eso, no dispone de órdenes o sentencias que capturen datos introducidos por teclado, ni tampoco para visualizar datos en la pantalla. Pero Oracle incorpora el paquete DBMS_OUTPUT con fines de depuración, que incluyen el procedimiento PUT_LINE, que permite visualizar textos en la pantalla.

El formato genérico es: DBMS_OUTPUT.PUT_LINE (<expresión>);

Para que funcione correctamente, la variable de entorno SERVEROUTPUTdeberá estar en ON. Para cambiar el estado de esta variable:SQL> SET SERVEROUTPUT ON

Para pasar datos a un programa podemos recurrir a:

- Introducir datos en una tabla desde SQL*Plus y después leerlos desde el programa.

- Utilizar variables de sustitución (en bloques anónimos).- Pasar los datos como parámetros en la llamada (en procedimientos y

funciones).

3. Interacción con el usuario en PL/SQL

Page 13: DAI PLSQL

TEMA 12: INTRODUCCIÓN AL LENGUAJE PL/SQL

4.1. Bloques anónimosNo tienen nombre. Se suelen crear y ejecutar desde SQL*Plus. Oracle reconoce el

comienzo de un bloque anónimo cuando encuentra la palabra DECLARE o BEGIN.

La última línea del bloque debe ser un punto. Esto provoca que se guarde todo en el buffer SQL. Una vez guardado, podremos ejecutarlo mediante la orden RUN o usar / en vez de un punto lo que hará que además de guardarlo lo ejecutará. El bloque del buffer se puede guardar en un fichero con la orden:SQL> SAVE nombrefichero [REPLACE]

La opción REPLACE se usará si el fichero ya existía.Para cargar un bloque de un fichero en el buffer SQL: SQL> GET nombreficheroUna vez cargado se puede ejecutar con RUN o /También se puede cargar y ejecutar con una sola orden:SQL> START nombrefichero

Ejemplo: Bloque que escribe nuestro nombre:SQL> BEGIN2 DBMS_OUTPUT.PUT_LINE (‘Nombre’);3 END;4 /Nombre. Procedimiento PL/SQLterminado con éxito

4. Uso y ejemplos de bloques anónimos y procedimientos

Page 14: DAI PLSQL

TEMA 12: INTRODUCCIÓN AL LENGUAJE PL/SQL

Ejemplo: Bloque que muestra el precio del producto especificadoSQL> DECLARE2 vprecio NUMBER;3 BEGIN4 SELECT precio_uni INTO vprecio5 FROM Productos6 WHERE cod_Producto = 7;7 DBMS_OUTPUT.PUT_LINE (vprecio);8 END;9 /

20000Procedimiento PL/SQLterminado con éxito

En los bloques PL/SQL se pueden utilizar variables de sustitución del SQL*Plus anteponiendo el & a la variable. Antes de ejecutar el bloque se solicitará valor para la variable:

4. Uso y ejemplos de bloques anónimos y procedimientos

Page 15: DAI PLSQL

TEMA 12: INTRODUCCIÓN AL LENGUAJE PL/SQLEjemplo: Bloque que muestra el precio del producto especificadoSQL> DECLARE2 vnomb Clientes.Nombre%TYPE;3 BEGIN4 SELECT nombre INTO vnomb5 FROM Clientes6 WHERE Nif = ‘&VS_nif’;7 DBMS_OUTPUT.PUT_LINE (vnomb);8 END;9 /SQL> Introduzca un valor para VS_nif: 123456Cantiguo 6: WHERE NIF=’&VS_nif’;nuevo 6: WHERE NIF=’123456C’MARIA

Además los nombres se pueden anidar para distintos propósitos:DECLARE…BEGIN….DECLARE

…BEGIN

……EXCEPTION…END;

4. Uso y ejemplos de bloques anónimos y procedimientos

Page 16: DAI PLSQL

TEMA 12: INTRODUCCIÓN AL LENGUAJE PL/SQL

4.2. Uso de procedimientosEjemplo: Procedimiento PL/SQL sencillo para consultar los datos de un cliente:SQL> CREATE OR REPLACE PROCEDURE Ver_Cliente (nomcli VARCHAR2)2 IS3 NifCli VARCHAR2(10);4 DomCli VARCHAR2(15);5 BEGIN6 SELECT nif, domicilio INTO NifCli, DomCli7 FROM Clientes WHERE nombre = nomcli;8 DBMS_OUTPUT.PUT_LINE (‘Nombre: ‘ ||nomcli|| ‘NIF: ‘|| nifcli || ‘Domiclio ‘|| domcli);9 EXCEPTION10 WHEN NO_DATA_FOUND THEN 11 DBMS_OUTPUT.PUT_LINE (‘No encontrado el cliente’ || nomcli);12 END;13 /

Procedimiento creado

4. Uso y ejemplos de bloques anónimos y procedimientos

Page 17: DAI PLSQL

TEMA 12: INTRODUCCIÓN AL LENGUAJE PL/SQL

Si el compilador detecta errores saldrá el siguiente mensaje: Procedimiento creado con errores de compilación

La orden SHOW ERRORS permite ver los errores detectados.

El procedimiento se encuentra almacenado en el servidor de la BD y puede ser invocado desde cualquier estación por cualquier usuario autorizado y con cualquier herramienta; por ejemplo desde SQL*Plus mediante la orden

EXECUTE:SQL> EXECUTE Ver_Cliente (‘Antonio’);O también se puede invocar a procedimiento desde un bloque PL/SQL:SQL> BEGIN Ver_Cliente (‘Antonio’); END;

Podemos insertar comentarios:- De línea con “--“- De varias líneas con /* <comentario> */

4. Uso y ejemplos de bloques anónimos y procedimientos

Page 18: DAI PLSQL

TEMA 12: INTRODUCCIÓN AL LENGUAJE PL/SQL

Ejemplo: Visualiza el precio de un producto cuyo código se pasa como parámetro

SQL> CREATE OR REPLACE PROCEDURE Ver_Precio (vCodProd NUMBER)3 IS 4 vPrecio NUMBER;5 BEGIN6 SELECT precio_uni INTO vPrecio FROM Productos WHERE

Cod_Producto = vCodProd;7 DBMS_OUTPUT.PUT_LINE (vPrecio);8 END;9 /Procedimiento creadoSQL> EXECUTE Ver_Precio(7);

4. Uso y ejemplos de bloques anónimos y procedimientos

Page 19: DAI PLSQL

TEMA 12: INTRODUCCIÓN AL LENGUAJE PL/SQL

Ejemplo: Modificar el precio de un producto cuyo código se pasa como parámetro junto con el nuevo precio. El procedimiento comprobará que la variación de precio no supere el 20%

CREATE OR REPLACE PROCEDURE Modificar_Precio (PCodProd NUMBER, PnuevoPrecio NUMBER)ISPrecioAnt NUMBER(5);BEGINSELECT Precio_uni INTO PrecioAnt FROM Productos WHERE Cod_Producto = PCodProd;IF (PrecioAnt * 0.20) > ABS (PrecioAnt - PnuevoPrecio)

THEN UPDATE Productos SET Precio_uni=PNuevoPrecio WHERE Cod_Producto=PCodProd;

ELSE DBMS_OUTPUT.PUT_LINE ('Error modificación superior al 20%');END IF;EXCEPTIONWHEN NO_DATA_FOUND THEN

DBMS_OUTPUT.PUT_LINE (‘No encontrado el producto’ ||PcodProd);END;

Execute Modificar_Precio (7, 50000);Error modificación superior al 20%

4. Uso y ejemplos de bloques anónimos y procedimientos

Page 20: DAI PLSQL

PROGRAMACIÓN EN L4G Y HERRAMIENTAS CASE

TEMA 13: FUNDAMENTOS DEL LENGUAJE PL/SQL

1. TIPOS DE DATOS BÁSICOS2. IDENTIFICADORES3. VARIABLES

3.1. DECLARACIÓN E INICIALIZACIÓN DE VARIABLES3.2. USO DE LOS ATRIBUTOS %TYPE Y%ROWTYPE3.3. CONSTANTES3.4. ÁMBITO Y VISIBILIDAD DE LAS VARIABLES

4. OPERADORES5. FUNCIONES DE SQL6. SENTENCIA GOTO7. SUBPROGRAMAS

7.1. PROCEDIMIENTOS7.2. FUNCIONES7.3. PARÁMETROS

Page 21: DAI PLSQL

TEMA 13: FUNDAMENTOS DEL LENGUAJE PL/SQL

1. Tipos de datos básicos

Se dispone de los mismos tipos de datos que SQL, además de otros propios: CHAR(n) VARCHAR2 (n) LONG(n) NUMBER(p,e) BOOLEAN DATE RAW(n)LONG RAW ROWID

2. Identificadores

Se utilizan para nombrar los objetos que intervienen en un programa: variables, constantes, cursores, excepciones, procedimientos, funciones, etiquetas,…

Pueden tener hasta 30 caracteres, empezando siempre por una letra, que puede ir seguida por letras, números, el signo de dólar ($) , de almohadilla (#) y el subguión ( _).

PL/SQL no diferencia entre mayúsculas y minúsculas.

1. Tipos de datos básicos y 2. Identificadores

Page 22: DAI PLSQL

TEMA 13: FUNDAMENTOS DEL LENGUAJE PL/SQL

3.1. Declaración e inicialización de variablesLas variables deben declararse antes de su uso. Formato: <nombreVariable> <tipo> [NOT NULL] [ { := | DEFAULT } <valor> ]No se pueden indicar una lista de variables del mismo tipo y a continuación el tipo.

3.2. Uso de los atributos %TYPE y %ROWTYPEPara declarar variables del mismo tipo que otros objetos ya definidos:

- %TYPE Declara una variable del mismo tipo que otra, o que una columna de una tabla.

- %ROWTYPE Crea una variable registro cuyos campos se corresponden con lascolumnas de una tabla o vista de datos.

3.3. ConstantesSe pueden declara constantes mediante el siguiente formato:

<nombreVariable> CONSTANT <tipo>:= <valor>

3.4. Ámbito y visibilidad de las variablesLa variable será local para el bloque en el que ha sido declarada y global para los bloques hijos de éste. Las variables declaradas en los bloques hijos no son accesibles desde el bloque padre.

3. Variables

Page 23: DAI PLSQL

TEMA 13: FUNDAMENTOS DEL LENGUAJE PL/SQL

4. Operadores

+ - * / **Aritméticos

= != < > <= >=IS NULL IS NOT NULLBETWEEN NOT BETWEENLIKE NOT LIKEIN NOT IN

Comparación

||Concatenación

AND OR NOT

Lógicos

:=Asignación

NULLFNULLNULL

FFFF

NULLFTT

NULLFTAND

NULLNULLTNULL

NULLFTF

TTTT

NULLFTOR

NULLTF

NULLFTNOT

Page 24: DAI PLSQL

TEMA 13: FUNDAMENTOS DEL LENGUAJE PL/SQL

Las mismas que en SQL: AVG, MIN, MAX, COUNT, SUM,…

Hay que tener en cuenta 2 aspectos:- La función no modifica el valor de las variables o expresiones que se pasan

como argumentos, sino que devuelve un valor a partir de dicho argumento.- Si a una función se le pasa un valor nulo en la llamada, normalmente

devolverá un valor nulo.BEGINDBS_OUTPUT.PUT_LINE(TO_CHAR(SYSDATE,’DAY,DD MONTH “ A LAS “YYYY:HH24:MI:SS’));END;/LUNES , 01 ENERO A LAS 2008:01:13:48Procedimiento PL/SQL terminado con éxito.

Se puede usar la cláusula GOTO etiqueta. Pero para poder usarla se deben cumplir las siguientes condiciones:

- No puede haber otra etiqueta en el entorno actual con el mimo nombre.- La etiqueta debe preceder a un bloque o a un conjunto de órdenes ejecutables- La etiqueta no puede estar dentro de un IF, de un LOOP ni de un SubBloque

internos al bloque donde se produce la llamada.

5. Funciones de SQL y 6. Sentencia GOTO

Page 25: DAI PLSQL

TEMA 13: FUNDAMENTOS DEL LENGUAJE PL/SQL

7.1. ProcedimientosCREATE [OR REPLACE] PROCEDURE nombre [(param [IN | OUT | INOUT] <tipo>) ][IS|AS]BEGIN<codigo del procedimiento>[EXCEPTION]END;

7.2. FuncionesCREATE [OR REPLACE] FUNCTION nombre [(param [IN | OUT | INOUT] <tipo>)]RETURN tipo

[IS|AS]BEGIN<codigo de la funcion>RETURN <valor o expresión>[EXCEPTION]END;

La cláusula RETURN de la cabecera especifica el tipo del valor que retorna la función. En el cuerpo del programa se hará efectivo ese retorno utilizando RETURN junto con la expresión cuyo valor se devolverá o con el valor en sí.Esta cláusula devuelve el control al programa que llamó a la función, asignando el valor devuelto por la función al identificador de la misma en el punto de la llamada. 7. Subprogramas

Page 26: DAI PLSQL

TEMA 13: FUNDAMENTOS DEL LENGUAJE PL/SQL

7.3. ParámetrosLos subprogramas utilizan parámetros para pasar y recibir información.

Hay 2 clases:

- Parámetros actuales o reales: son las variables o expresiones indicadas en la llamada a un subprograma.

- Parámetros formales: Son variables declaradas en la especificación del subprograma.

Si es necesario podemos hacer el paso de parámetros utilizando las notaciones:

- Posicional: compilador asocia los parámetros actuales a los formales basándose en suposición.

- Nominal: el símbolo => después del parámetro actual y antes del nombre del formal indica al compilador la correspondencia.

- Mixta: usar ambas notaciones.

7. Subprogramas

Page 27: DAI PLSQL

TEMA 13: FUNDAMENTOS DEL LENGUAJE PL/SQL

7.3. ParámetrosLos parámetros pueden ser de Entrada, Salida o de E/S.

7. Subprogramas

Permite pasar un valor inicial y devolver un valor actualizado. Dentro del subprograma, el parámetro actúa como una variable inicializada. Puede intervenir en otras expresiones y puede tomar nuevos valores..El parámetro actual debe ser una variable.

IN OUT

Permite devolver valores al bloque que llamó al subprograma. Dentro del subprograma, el parámetro actúa como una variable no inicializada.El parámetro actual debe ser una variable.

OUT

Permite pasar valores a un subprograma. Dentro del subprograma, el parámetro actúa como una constante, es decir, no se le puede asignar ningún valor.El parámetro actual puede ser una variable, constante, literal o expresión

IN

Page 28: DAI PLSQL

PROGRAMACIÓN EN L4G Y HERRAMIENTAS CASE

TEMA 14: CURSORES Y EXCEPCIONES EN PL/SQL

1. CURSORES EXPLÍCITOS

2. ATRIBUTOS DEL CURSOR

3. VARIABLES DE ACOPLAMIENTO EN EL MANEJO DE CURSORES

4. CURSOR FOR...LOOP

5. ATRIBUTOS CON CURSORES EXPLÍCITOS

6. EXCEPCIONES6.1. EXCEPCIONES INTERNAS PREDEFINIDAS6.2. EXCEPCIONES PREDEFINIDAS POR EL USUARIO

Page 29: DAI PLSQL

TEMA 14: CURSORES Y EXCEPCIONES EN PL/SQL

Hasta ahora hemos utilizado cursores implícitos, cuando devolvíamos el resultado de una SELECT mediante la cláusula INTO a una variable. Pero esto es un problema cuando el resultado de una subconsulta devuelve más de una fila.

En estos casos se manejan los cursores explícitos.

Se usan para trabajar con consultas que pueden devolver más de una fila. Hay 4 operaciones básicas para trabajar con un cursor explícito:

1. Declaración del cursor: en la zona de declaraciones según el formato:CURSOR <nombreCursor> IS SELECT <sentencia select> ;

2. Apertura del cursor: en la zona de instrucciones hay que abrir el cursor con el siguiente formato:

OPEN <nombreCursor>;

Al hacerlo se ejecuta automáticamente la sentencia SELECT asociada y sus resultados se almacenan en las estructuras internas de memoria manejadas por el cursor. Para acceder a la información debemos dar el paso 3

1. Cursores explícitos

Page 30: DAI PLSQL

TEMA 14: CURSORES Y EXCEPCIONES EN PL/SQL

3. Recogida de información: almacenada en el cursor, se utiliza el siguiente formato:FETCH <nombreCursor> INTO { <variable> | < lista de

variables > };

Después del INTO figurará una variable que recogerá la información de todas las columnas.

En este caso, la variable puede ser declarada de esta forma:<variable > <nombrecursor>%ROWTYPE

O una lista de variables. Cada una recogerá la columna correspondiente de la cláusula SELECT; por tanto serán del mismo tipo que las columnas. Cada FETCHrecupera una fila y el cursor avanza automáticamente a la fila siguiente.

4. Cierre del cursor: cuando no se va a utilizar más hay que cerrarlo.CLOSE <nombreCursor>

1. Cursores explícitos

Page 31: DAI PLSQL

TEMA 14: CURSORES Y EXCEPCIONES EN PL/SQL

Ejemplo:DECLARECURSOR C1 IS SELECT NOMBRE, APELLIDO FROM ARBITRO;

Vnom VARCHAR2(15);Vapel VARCHAR2 (20;

BEGINOPEN C1;LOOP

FETCH C1 INTO vNom, vApel;EXIT WHEN C1%NOTFOUND;DBMS_OUTPUT.PUT_LINE ( vNom || ‘ ‘ || vApel);

END LOOP;CLOSE C1;END;

Observar que en la sentencia SELECT en la declaración del cursor no contiene la cláusula INTO para indicar las variables que recibirán la información. Esta cláusula INTO se especifica cada vez que se realiza un FETCH. Después de un FETCH debe comprobarse el resultado. Lo que se suele hacer preguntando por el valor de alguno de los atributos del cursor.

1. Cursores explícitos

Page 32: DAI PLSQL

TEMA 14: CURSORES Y EXCEPCIONES EN PL/SQL

Para conocer detalles respecto a l situación del cursor hay 4 atributos:

- %FOUND: devuelve verdadero si el último FETCH ha recuperado algún valor; en caso contrario, devuelve falso. Si el cursor no estaba abierto devuelve error, y si estaba abierto pero no se había ejecutado aún ningún FETCH, devuelve NULL. Se suele utilizar como condición de continuación en bucles para recuperar información.

- %NOTFOUND: Hace lo contrario que el atributo anterior.- %ROWCOUNT: Devuelve el nº de filas recuperadas hasta el momento por el cursor (nº

de FETCH realizados satisfactoriamente).- %ISOPEN: Devuelve verdadero si el cursor está abierto.

Ejemplo:DECLARE

CURSOR C1 IS SELECT NOMBRE, APELLIDO FROM ARBITRO;Vnom VARCHAR2(15);VapelVARCHAR2 (20;

BEGINOPEN C1;FETCH C1 INTO vNom, vApel;WHILE C1%FOUND LOOP

DBMS_OUTPUT.PUT_LINE ( vNom || ‘ ‘ || vApel);FECH C1 INTO vNom, vApel;

END LOOP;CLOSE C1;

END;2. Atributos del cursor

Page 33: DAI PLSQL

TEMA 14: CURSORES Y EXCEPCIONES EN PL/SQL

Ejemplo:DECLARE

CURSOR C1 IS SELECT Nombre FROM Futbolista WHERE CodEq= ‘E1’;Vnom VARCHAR2(15);

BEGINOPEN C1;LOOP

FETCH C1 INTO vNom;DBMS_OUTPUT.PUT_LINE (C1%ROWCOUNT|| vNom);EXIT WHEN C1%NOTFOUND;

END LOOP;CLOSE C1;

END;

El programa anterior está mal diseñado ya que visualiza la información supuestamente recuperada antes de comprobar si se ha recuperado información.

2. Atributos del cursor

Page 34: DAI PLSQL

TEMA 14: CURSORES Y EXCEPCIONES EN PL/SQL

En el ejemplo siguiente podemos observar que en la cláusula WHERE se incluye una variable que se deberá haber declarado previamente. Este tipo de variables recibe el nombre de variables de acoplamiento. El programa la sustituirá por su valor en el momento en que se abre el cursor, y se seleccionarán las filas según dicho valor. Aunque ese valor cambie durante la recuperación de los datos con FETCH, el conjunto de filas que contiene el cursor no variará.

Ejemplo: Visualizar los futbolistas de un equipo cualquieraCREATE OR REPLACE PROCEDURE Ver_Futobolsita_Por_Equipos (pCodEq VARCHAR2)IS

vEqui VARCHAR2(3);CURSOR C1 IS SELECT Nombre FROM Futbolista WHERE CodEq= vEqui;

Vnom VARCHAR2(15);BEGIN

vEqui := pCodEq;OPEN C1;FETCH C1 INTO vNom;WHILE C1%FOUND LOOP

DBMS_OUTPUT.PUT_LINE (vNom);FETCH C1 INTO vNom;

END LOOP;CLOSE C1;

END;

3. Variables de acoplamiento en el manejo de cursores

Page 35: DAI PLSQL

TEMA 14: CURSORES Y EXCEPCIONES EN PL/SQL

El trabajo con un cursor consiste en: declarar un cursor, declarar una variables que recogerá los datos del cursor; abrir el cursor; recuperar con FETCH una a una las filas extraídas, introduciendo los datos en las variables, procesándolos y comprobando también si se han recuperado datos o no, y Cerrar el cursor.

Por eso, PL/SQL proporciona le estructura cursor…FOR…LOOP, que simplifica estas tareas realizando todas ellas, excepto la declaración de cursor, de manera implícita.

El formato y el uso de esta estructura es:

1º Se declara la información cursor en la sección correspondiente (como cualquier otro cursor).2º Se procesa el cursor utilizando el siguiente formato: FOR nombreVarReg IN nombreCursor LOOP … END LOOP;

4. Cursor FOR...LOOP

Page 36: DAI PLSQL

TEMA 14: CURSORES Y EXCEPCIONES EN PL/SQL

Al entrar en el bucle se abre el cursor de manera automática, se declara implícitamente la variable nombreVarReg de tipo nombrecursor%ROWTYPE y se ejecuta el primer FETCH, cuyo resultado quedarán en nombreVarReg. A continuación se realizarán las acciones que correspondan hasta llegar al END LOOP, que sube de nuevo al FOR…LOOP ejecutando el siguiente FETCH, y depositando otra vez el resultado en nombreVarReg y así sucesivamente, hasta procesar la última fila de la consulta, momento en el que se producirá la salida del bucle y se cerrará automáticamente el cursor.

Ejemplo:DECLARE

CURSOR C2 IS SELECT nombre, peso, estatura FROM FutbolistaWHERE salario > 1800;BEGIN

FOR vReg IN C2 LOOPDBMS_OUTPUT.PUT_LINE (vreg.Nombre ||’ – ‘ || vreg.Peso ||’ –

‘ || vreg.Estatura);END LOOP;

END;

4. Cursor FOR...LOOP

Page 37: DAI PLSQL

TEMA 14: CURSORES Y EXCEPCIONES EN PL/SQL

Oracle abre implícitamente un cursor cuando procesa un comando SQL que no estéasociado a un cursor explícito. El cursor implícito se llama SQL y supone también de los 4 atributos mencionados, que pueden facilitarnos información sobre la ejecución de los comandos SELECT INTO, INSERT, UPDATE y DELETE.El valor de los atributos del cursor SQL se refiere en cada momento a la última orden SQL.

- SQL%NOTFOUND: dará true si el último INSERT, UPDATE, DELETE O SELECT INTO han fallado (no han afectado a ninguna fila).

- SQL%FOUND: dará true si el último INSERT, UPDATE, DELTE o SELECT INTOhan afectado a una o más filas.

- SQL%ROWCOUNT: devuelve el nº de filas afectadas por el último INSERT, UPDATE, DELETE o SELECT INTO.

- SQL%ISOPEN: siempre devolverá falso ya que Oracle cierra automáticamente el cursor después de cada orden SQL.

Es preciso hacer algunas observaciones respecto al uso de atributos en cursores implícitos: el comportamiento de los atributos en los cursores implícitos es distinto al de los cursores explícitos. De hecho, como acabamos de ver, el cursor estará cerrado inmediatamente después de procesar la orden SELECT INTO que es cuando se pregunta por su atributo o atributos (lo cual debería determinar una situación de error).

5. Atributos con cursores explícitos

Page 38: DAI PLSQL

TEMA 14: CURSORES Y EXCEPCIONES EN PL/SQL

A continuación se especifican algunas peculiaridades en el comportamiento y uso de los atributos en cursores implícitos:

- Devolverán un valor relativo a la última orden INSERT, UPDATE, DELETE o SELECT INTO aunque el cursor esté cerrado.

- En el caso de que se trate de un SELECT INTO debemos tener en cuenta que ha de devolver una fila y sólo una, pues de de lo contrario se producirá un error y se levantará automáticamente una excepción:

- NO_DATA_FOUND si la consulta no devuelve ninguna fila- TOO_MANY_ROWS si la consulta devuelve más de una fila.- Se detendrá la ejecución normal del programa y bifurcará a la sección EXCEPTION.

Por tanto, cualquier comprobación de la situación del cursor en esas circunstancias resulta inútil.

- Lo indicado en el punto anterior no es aplicable a las órdenes INSERT, UPDATE, DELETE ya que en estos casos no se levantan las excepciones correspondientes.

5. Atributos con cursores explícitos

Page 39: DAI PLSQL

TEMA 14: CURSORES Y EXCEPCIONES EN PL/SQL

Ejemplo:DECLAREvDpto Departamentos.Nombre%TYPE;vLoc Departamentos.Localidad%TYPE;BEGINvDpto := ‘MARKETING’; /* No existe Marketing */UPDATE Departmentos SET Localidad=’Madrid’ WHERE Nombre= vDpto; /*

Fallará*/IF SQL%NOTFOUND THENDBMS_OUTPUT.PUT_LINE (‘Error en la aplicación’);END IF;DBMS_OUTPUT.PUT_LINE (‘continua el programa’);SELECT localidad INTO VLoc FROM Departamentos WHERE

Nombre=vDpto;/*Fallará*/IF SQL%NOTFOUND THENDBMS_OUTPUT.PUT_LINE (‘Imposible nunca pasará por aquí’);END IF;END;

5. Atributos con cursores explícitos

Page 40: DAI PLSQL

TEMA 14: CURSORES Y EXCEPCIONES EN PL/SQL

Cuando un SELECT INTO hace referencia a una función de grupo nunca se levantará la excepción NO_DATA_FOUND y SQL%FOUND siempre seráverdadero. Esto se debe a que las funciones de grupo siempre retornan algún valor (aunque sea NULL).

Ejemplo:BEGIN…SELECT MAX(salario) INTO vmaxFROM Emple WHERE NumDpto := VDpto; /* Nunca levantará NO_DATA_FOUND

*/IF SQL%NOTFOUND THEN /* Nunca sera cierto */… /* Nunca se ejecutará */END IF;EXCEPTIONWHEN NO_DATA_FOUND THEN …. /* No sera invocado*/END;

5. Atributos con cursores explícitos

Page 41: DAI PLSQL

TEMA 14: CURSORES Y EXCEPCIONES EN PL/SQL

Las excepciones sirven para tratar errores en tiempo de ejecución, y errores y situaciones definidas por el usuario. Cuando se produce un error PL/SQL levanta una excepción y pasa el control a la sección EXCEPTION correspondiente del bloque, que actuará según lo establecido y dará por finalizada la ejecución del bloque actual.Formato de la sección EXCEPTION:EXCEPTION

WHEN <nombreExcepción1> THEN <instrucciones>;WHEN <nombreExcepción2> THEN <instrucciones>;…[ WHEN OTHERS THEN <instrucciones>; ]

6.1. Excepciones internas predefinidasSe disparan automáticamente al producirse determinados errores. Las más frecuentes son:

6. Excepciones

Se intenta almacenar un valor que crearía duplicados en la clave primaria o en una columna con la restricción UNIQUE

DUPVAL_ON_INDEX-1ORA-00001

Intentamos abrir un cursor que ya se encuentra abierto

CURSOR_ALREADY_OPEN-6511ORA-06511

Se intenta acceder a elementos de una colección que no ha dio inicializada

COLLECTION_IS_NULL-6531ORA-06531

Se intenta acceder a los atributos de un objeto no inicializado

ACCESS_INTO_NULL-6530ORA-06530

Se disparan cuando…ExcepciónValor SQL CODECódigo error Oracle

Page 42: DAI PLSQL

TEMA 14: CURSORES Y EXCEPCIONES EN PL/SQL

6. Excepciones

Se excede el tiempo de espera para un recurso.

TIMEOUT_ON_RESOURCE-51ORA-00051

El bloque PL/SQL se ejecuta fuera de memoria (o hay algún otro error de memoria).

STORAGE_ERROR-6500ORA-06500

Se intenta acceder a una tabla anidada o a un array con un valor de índice ilegal (por ejemplo, negativo)

SUBSCRIPT_OUTSIDE_LIMT-6533ORA-06533

La variable del cursor del HOST y la variable del cursor PL/SQL pertenecen a tipos incompatibles

ROWTYPE_MISMATCH-6504ORA-06504

Hay un problema interno en la ejecución del programa

PROGRAMA_ERROR-6501ORA-06501

NODATA_FOUND+100ORA-01403

Reintenta acceder a la BD sin estar conectado a Oracle

NOT_LOGGED_ON-1012ORA-01012

Se intenta conectar a ORACLE con un usuario o una clave no válidos

LOGIN_DENIED-1017ORA-01017

Fallo al intentar convertir una cadena a un valor numérico

INVALID_NUMBER-1722ORA-01722

Se intenta realizar una operación no permitida sobre un cursor (por ejemplo, cerrar un cursor que no se ha abierto)

INVALID_CURSOR-1001ORA-01001

Se disparan cuando…ExcepciónValor SQL CODECódigo error Oracle

Page 43: DAI PLSQL

TEMA 14: CURSORES Y EXCEPCIONES EN PL/SQL

No hay que declararlas en la sección DECLARE

6.2. Excepciones definidas por el usuarioPara su utilización hay que dar 3 pasos:

1. Se deben declarar en la sección DECLARE de la forma siguiente: <nombreExcepción> EXCEPTION;

2. Se disparan o levantan en la sección ejecutable del programa con la orden RAISE: RAISE <nombreExcepción>;

3. Se tratan en la sección EXCEPTION según el formato ya conocido WHEN <nombreexcepción> THEN <tratamiento>;

6. Excepciones

Se intenta la división entre cero.ZERO_DIVIDE-1476ORA-01476

Un error de tipo aritmético, de conversión, de truncamiento,…

VALUE_ERROR-6502ORA-06502

TO_MANY_ROWS-1422ORA-01422

Se disparan cuando…ExcepciónValor SQL CODECódigo error Oracle

Page 44: DAI PLSQL

TEMA 14: CURSORES Y EXCEPCIONES EN PL/SQL

Ejemplo: El siguiente ejemplo utiliza una excepción predefinida y otra definida por el programador:

PROCEDURE SUBIR_SALARIO (num_emple INTEGER, incremento REAL)IS

salario_actual REAL;salario_nulo EXCEPTION;

BEGINSELECT salario INTO salario_actual FROM emple WHERE emp_no=num_emple;IF salario_actual IS NULL THEN RAISE salario_nulo;ELSE UPDATE emple SET salario=salario+incremento WHERE emp_no=num_emple;END IF;EXCEPTIONWHEN NO_DATA_FOUND THEN DBMS_OUTPUT.PUT_LINE (num_emple|| ‘*Error. No encontrado’);WHEN salario_nulo THEN DBMS_OUTPUT.PUT_LINE (num_emple|| ‘*Error. Salario nulo’);

END SUBIR_SALARIO;

6. Excepciones

Page 45: DAI PLSQL

PROGRAMACIÓN EN L4G Y HERRAMIENTAS CASE

TEMA 15: TRIGGERS EN PL/SQL

1. INTRODUCCIÓN

2. DECLARACIÓN DE TRIGGERS

3. ORDEN DE EJECUCIÓN DE LOS TRIGGERS

4. RESTRICCIONES DE LOS TRIGGERS

5. UTILIZACIÓN DE :OLD Y :NEW

6. UTILIZACIÓN DE PREDICADOS: INSERTING, UPDATING Y DELETING

Page 46: DAI PLSQL

TEMA 15: TRIGGERS EN PL/SQL

Los triggers o disparadores de BD son bloques PL/SQL almacenados asociados a una tabla que se ejecutan o disparan automáticamente cuando se producen ciertos eventos o sucesos que afectan a la tabla (inserción, borrado o modificación de filas).

Se suelen utilizar para:

− Implementar restricciones complejas de seguridad o integridad.

− Prevenir transacciones erróneas.− Implementar reglas administrativas complejas.− Generar automáticamente valores derivados... Etc.

1. Introducción

Page 47: DAI PLSQL

TEMA 15: TRIGGERS EN PL/SQL

CREATE [OR REPLACE] TRIGGER <nombre_trigger>{BEFORE|AFTER} {DELETE|INSERT|UPDATE [OF col1, col2, ..., colN][OR {DELETE|INSERT|UPDATE [OF col1, col2, ..., colN]...]}ON <nombre_tabla>[FOR EACH ROW [WHEN (<condicion>)] | FOR EACH STATEMENT]DECLARE/* variables locales*/BEGIN[EXCEPTION <gestión de excepciones>]END <nombre_trigger>;

El uso de OR REPLACE permite sobrescribir un trigger existente. Si se omite, y el trigger existe, se producirá, un error. Los triggers pueden definirse para las operaciones INSERT, UPDATE o DELETE, y pueden ejecutarse antes o después de la operación. El modificador BEFORE AFTER indica que el trigger se ejecutará antes o después de ejecutarse la sentencia SQL definida por DELETE INSERT UPDATE. Si incluimos el modificador OF el trigger solo se ejecutarácuando la sentencia SQL afecte a los campos incluidos en la lista.El alcance de los disparadores puede ser la fila o de orden (se activará una sóla vez para cada orden, independientemente del nº de filas afectadas). El modificador FOR EACH ROWindica que el trigger se disparará cada vez que se realizan operaciones sobre una fila de la tabla. Si se acompaña del modificador WHEN, se establece una restricción; el trigger solo actuará, sobre las filas que satisfagan la restricción.

2. Declaración de triggers

Page 48: DAI PLSQL

TEMA 15: TRIGGERS EN PL/SQL

Ejemplo: Crear el trigger audit_subida_salario que se disparará después de cada modificaciónde la columna de la tabla EMPLE:

CREATE OR REPLACE TRIGGER AUDIT_SUBIDA_SALARIOAFTER UPDATE OF SALARIO ON EMPLE FOR EACH ROWBEGIN

INSERT INTO AUDITARAEMPLE VALUES ('SUBIDA SALARIO EMPLEADO',:OLD.EMP_NO);END;

El disparador insertará una fila en la tabla auditaraemple con el texto ‘SUBIDA SALARIO EMPLEADO’ y el número del empleado al que se le ha subido el salario.

Ejemplo: Crear el trigger audit_borrado_emple que se disparará cada vez que se borre un empleado, guardando su número, apellido y departamento en una fila de la tablaAUDITARAEMPLE:

CREATE OR REPLACE TRIGGER audit_borrado_empleBEFORE DELETE ON empleFOR EACH ROW BEGIN

INSERT INTO auditaraemple VALUES (‘BORRADO EMPLEADO ’||’*’||:OLD.emp_no|| ‘*’||:OLD.apellido || ‘*’||:OLD.dept_no);

END;

2. Declaración de triggers

Page 49: DAI PLSQL

TEMA 15: TRIGGERS EN PL/SQL

La siguiente tabla resume los contenidos anteriores.

2. Declaración de triggers

Se asume por omisión.FOR EACH STATEMENT

Los disparadores con nivel de fila se activan una vez por cada fila afectada por la orden que provocó el disparo. Los disparadores con nivel de orden se activan sólo una vez, antes o después de la orden. Los disparadores con nivel de fila se identifican por la cláusula FOR EACH ROW en la definición del disparador.

FOR EACH ROW

Define si el disparador se activa antes o después de que se ejecute la orden.

BEFORE , AFTER

Define qué tipo de orden DML (INSERT, DELETE o UPDATE) provoca la activación del disparador.

INSERT, DELETE, UPDATE

DescripciónValor

Page 50: DAI PLSQL

TEMA 15: TRIGGERS EN PL/SQL

La cláusula WHEN sólo es válida para los disparadores con nivel de fila.Dentro del ámbito de un trigger disponemos de las variables OLD y NEW. Estas variables se utilizan del mismo modo que cualquier otra variable PL/SQL, con la salvedad de que no es necesario declararlas, son de tipo %ROWTYPE y contienen una copia del registro antes (OLD) y después (NEW) de la acción SQL (INSERT, UPDATE, DELETE) que ha ejecutado el trigger. Utilizando esta variable podemos acceder a los datos que se están insertando, actualizando o borrando.

Ejemplo: Trigger que inserta un registro en la tabla PRECIOS_PRODUCTOS cada vezque insertamos un nuevo registro en la tabla PRODUCTOS:

CREATE OR REPLACE TRIGGER tr_PRODUCTOSAFTER INSERT ON PRODUCTOS FOR EACH ROWBEGININSERT INTO PRECIOS_PRODUCTOS (COD_PROD,PRECIO,FECHA) VALUES

(:NEW.COD_PRODUCTO,100,SYSDATE);END;

El trigger se ejecutará cuando sobre la tabla PRODUCTOS se ejecute una sentencia INSERT.

INSERT INTO PRODUCTOS (COD_PRODUCTO, DESCRIPCION,LINEA_PRODUCTO,PRECIO_UNI,STOCK) VALUES ('10','TORNILLO','PROCES',500,0);

2. Declaración de triggers

Page 51: DAI PLSQL

TEMA 15: TRIGGERS EN PL/SQL

Una misma tabla puede tener varios triggers. En tal caso es necesario conocer el orden en el que se van a ejecutar.

Los disparadores se activan al ejecutarse la sentencia SQL.

• Si existe, se ejecuta el disparador de tipo BEFORE (disparador previo) con nivel de orden.

• Para cada fila a la que afecte la orden:• Se ejecuta si existe, el disparador de tipo BEFORE con nivel de

fila.• Se ejecuta la propia orden.• Se ejecuta si existe, el disparador de tipo AFTER (disparador

posterior) con nivel de fila.• Se ejecuta, si existe, el disparador de tipo AFTER con nivel de orden

FOR EACH STATEMENT.

3. Orden de ejecución de los triggers

Page 52: DAI PLSQL

TEMA 15: TRIGGERS EN PL/SQL

El cuerpo de un trigger es un bloque PL/SQL. Cualquier orden que sea legal en un bloque PL/SQL, es legal en el cuerpo de un disparador, con las siguientes restricciones:

• Un disparador no puede emitir ninguna orden de control de transacciones: COMMIT, ROLLBACK. El disparador se activa como parte de la ejecución de la orden que provocó el disparo, y forma parte de la misma transacción que dicha orden. Cuando la orden que provoca el disparo es confirmada o cancelada, se confirma o cancela también el trabajo realizado por el disparador.

• Por razones idénticas, ningún procedimiento o función llamado por el disparador puede emitir órdenes de control de transacciones.

• El cuerpo del disparador no puede contener ninguna declaración de variables LONG o LONG RAW.

4. Restricciones de los triggers

Page 53: DAI PLSQL

TEMA 15: TRIGGERS EN PL/SQL

Dentro del ámbito de un trigger disponemos de las variables OLD y NEW. Estas variables se utilizan del mismo modo que cualquier otra variable PL/SQL, con la salvedad de que no es necesario declararlas, son de tipo%ROWTYPE y contienen una copia del registro antes (OLD) y después(NEW) de la acción SQL (INSERT, UPDATE, DELETE) que ha ejecutado el trigger.

Utilizando esta variable podemos acceder a los datos que se están insertando, actualizando o borrando.

La siguiente tabla muestra los valores de OLD y NEW.

Los registros OLD y NEW son sólo válidos dentro de los disparadores con nivel de fila.

5. Utilización de :OLD y :NEW

No definidos; todos los campos toman el valor NULL.

Valores, antes del borrado de la fila.DELETE

Nuevos valores que serán escritos cuando se complete la orden.

Valores originales de la fila, antes de la actualización.

UPDATE

Valores que serán insertados cuando se complete la orden.

No definido; todos los campos toman valor NULL.

INSERT

NEWOLDACCION SQL

Page 54: DAI PLSQL

TEMA 15: TRIGGERS EN PL/SQL

Dentro de un disparador en el que se disparan distintos tipos de órdenes DML (INSERT, UPDATE y DELETE), hay tres funciones booleanas que pueden emplearse para determinar de qué operación se trata. Estos predicados son INSERTING, UPDATING y DELETING.

Su comportamiento es el siguiente:

6. Utilización de los predicados INSERTING, UPDATING Y DELETING

TRUE si la orden de disparo es DELETE; FALSE en otro caso.

DELETING

TRUE si la orden de disparo es UPDATE; FALSE en otro caso.

UPDATING

TRUE si la orden de disparo es INSERT; FALSE en otro caso.

INSERTING

COMPORTAMIENTOPREDICADO

Page 55: DAI PLSQL

TEMA 15: TRIGGERS EN PL/SQL

Ejemplo: Se puede cambiar a un empleado de departamento indicando solamente el nombre del departamento nuevo. El disparador se encargará de comprobar y asignar el número de departamento que corresponda. También se han limitado las columnas que hay que actualizar. En caso de que la operación no se contemple entre las alternativas, el trigger levantará un error en la aplicación haciendo que falle toda la actualización.CREATE VIEW EMPLEAD AS SELECT EMP_NO,APELLIDO,OFICIO,DNOMBRE,LOC FROM EMPLE, DEPART WHERE EMPLE.DEPT_NO=DEPART.DEPT_NO;

CREATE OR REPLACE TRIGGER t_ges_empleINSTEAD OF DELETE OR INSERT OR UPDATE ON EMPLEADFOR EACH ROWDECLARE

v_dep depart.dept_no%type;BEGIN

IF DELETING THEN DELETE FROM EMPLE WHERE emp_no=:OLD.emp_no;ELSIF INSERTING THEN SELECT dept_no INTO v_dep FROM depart WHERE

depart.dnombre=:NEW.dnombre AND loc=:NEW.loc;INSERT INTO EMPLE (emp_no, apellido, oficio, dept_no) VALUES (:NEW.emp_no,

:NEW.apellido, :NEW.oficio, v_dep);ELSIF UPDATING ('dnombre') THEN SELECT dept_no INTO v_dep FROM depart WHERE

dnombre=:NEW.dnombre;UPDATE emple SET dept_no=v_dep WHERE emp_no=:OLD.emp_no;

ELSIF UPDATING ('oficio') THEN UPDATE emple SET oficio=:NEW.oficio WHERE emp_no=:OLD.emp_no;

ELSERAISE_APPLICATION_ERROR(-20500,'Error en la actualización');

END IF;END; 6. Utilización de los predicados INSERTING, UPDATING Y DELETING