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

PROGRAMACIÓN EN L4G Y HERRAMIENTAS CASE

TEMA 12: INTRODUCCIÓN AL LENGUAJE PL/SQL

1. INTRODUCCIÓN
2. CARACTERÍSTICAS DEL LENGUAJE

2.1. BLOQUES PL / SQL


2.2. DEFINICIÓN DE DATOS COMPATIBLES CON PL / SQL
2.3. ESTRUCTURAS DE CONTROL
2.4. SOPORTE PARA ÓRDENES DE MANIPULACIÓN DE DATOS
2.5. USO DE CURSORES
2.6. GESTIÓN DE EXCEPCIONES
2.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ÓNIMOS


4.2. USO DE PROCEDIMIENTOS
TEMA 12: INTRODUCCIÓN AL LENGUAJE PL/SQL
9 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.
9 Los programas creados con PL/SQL se pueden almacenar en
la BD como cualquier otro objeto de ésta.

1. Introducción
TEMA 12: INTRODUCCIÓN AL LENGUAJE PL/SQL
9 PL/SQL es un lenguaje procedimental diseñado por Oracle
para trabajar con la BD.
9 Está incluido en el servidor y en algunas herramientas de
cliente.
9 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.
9 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


TEMA 12: INTRODUCCIÓN AL LENGUAJE PL/SQL
9 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.
9 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
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.

DECLARE
v_num_emple NUMBER(2);
BEGIN
INSERT 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


TEMA 12: INTRODUCCIÓN AL LENGUAJE PL/SQL
9 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:
DECLARE
Importe NUMBER(8,2);
Contador NUMBER(2) DEFAULT 0;
Nombre CHAR(20); NOT NULL := ‘MIGUEL’;
Nuevo VARCHAR2(15);
BEGIN

9 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;

9 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
TEMA 12: INTRODUCCIÓN AL LENGUAJE PL/SQL
2.3.1. Estructuras de control alternativas
Alternativa simple Alternativa doble Alternativa múltiple
IF <condición> THEN IF <condición> THEN IF <condición> THEN
instrucciones; instrucciones; instrucciones;
… … …
END IF; ELSE ELSIF <condición2> THEN
Instrucciones; Instrucciones;
… …
END IF; ELSIF <condición3> THEN
Instrucciones;

ELSE
Instrucciones;

END IF;

2.3.2. Estructuras de control repetitivas


Mientras Para Iterar… fin iterar salir si…
WHILE <condición> LOOP FOR <variable> IN <mínimo> . . LOOP
instrucciones; <máximo> LOOP instrucciones;
… instrucciones; …
END LOOP; … EXIT WHEN <condición>
END LOOP; Instrucciones

END LOOP;

2.3. Estructuras de control


TEMA 12: INTRODUCCIÓN AL LENGUAJE PL/SQL
9 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


TEMA 12: INTRODUCCIÓN AL LENGUAJE PL/SQL
9 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;

9 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:
DECLARE
vApe VARCHAR2(10);
vOficio VARCHAR2(10);
BEGIN
SELECT apellido, oficio INTO vApe, vOficio FROM Emple WHERE emp_no=7900;
DBMS_OUTPUT.PUT_LINE (vApe || ¡ -‘ || vOficio);
END;

2.5. Uso de Cursores


TEMA 12: INTRODUCCIÓN AL LENGUAJE PL/SQL
Ejemplo anterior con tratamiento de excepciones:
DECLARE
vApe VARCHAR2(10);
vOficio VARCHAR2(10);
BEGIN
SELECT apellido, oficio INTO vApe, vOficio FROM Emple WHERE
emp_no=7900;
DBMS_OUTPUT.PUT_LINE (vApe || ‘-‘ || vOficio);
EXCEPTION
WHEN NO_DATA FOUND THEN insert into Temp values (‘Noy hay datos’);
WHEN TOO_MANY_ROWS THEN insert into Temp values (‘Demasiados
datos);
WHEN OTHERS THEN RAISE_APPLICATION_ERROR (-20000, ‘Error en
aplicación’);
END;

9 Si PL/SQL detecta una excepción, pasa el control a la cláusula WHEN


correspondiente 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


TEMA 12: INTRODUCCIÓN AL LENGUAJE PL/SQL
9 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


TEMA 12: INTRODUCCIÓN AL LENGUAJE PL/SQL
9 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.
9 El formato genérico es: DBMS_OUTPUT.PUT_LINE (<expresión>);

9 Para que funcione correctamente, la variable de entorno SERVEROUTPUT


deberá estar en ON. Para cambiar el estado de esta variable:
SQL> SET SERVEROUTPUT ON

9 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


TEMA 12: INTRODUCCIÓN AL LENGUAJE PL/SQL
4.1. Bloques anónimos
9 No 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.

9 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]

9 La opción REPLACE se usará si el fichero ya existía.


9 Para cargar un bloque de un fichero en el buffer SQL: SQL> GET nombrefichero
9 Una vez cargado se puede ejecutar con RUN o /
9 También se puede cargar y ejecutar con una sola orden:
SQL> START nombrefichero
Ejemplo: Bloque que escribe nuestro nombre:
SQL> BEGIN
2 DBMS_OUTPUT.PUT_LINE (‘Nombre’);
3 END;
4 /
Nombre. Procedimiento PL/SQLterminado con éxito

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


TEMA 12: INTRODUCCIÓN AL LENGUAJE PL/SQL
Ejemplo: Bloque que muestra el precio del producto especificado
SQL> DECLARE
2 vprecio NUMBER;
3 BEGIN
4 SELECT precio_uni INTO vprecio
5 FROM Productos
6 WHERE cod_Producto = 7;
7 DBMS_OUTPUT.PUT_LINE (vprecio);
8 END;
9 /

20000
Procedimiento PL/SQLterminado con éxito

9 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


TEMA 12: INTRODUCCIÓN AL LENGUAJE PL/SQL
Ejemplo: Bloque que muestra el precio del producto especificado
SQL> DECLARE
2 vnomb Clientes.Nombre%TYPE;
3 BEGIN
4 SELECT nombre INTO vnomb
5 FROM Clientes
6 WHERE Nif = ‘&VS_nif’;
7 DBMS_OUTPUT.PUT_LINE (vnomb);
8 END;
9 /
SQL> Introduzca un valor para VS_nif: 123456C
antiguo 6: WHERE NIF=’&VS_nif’;
nuevo 6: WHERE NIF=’123456C’
MARIA
9 Además los nombres se pueden anidar para distintos propósitos:
DECLARE

BEGIN
….
DECLARE

BEGIN


EXCEPTION
… 4. Uso y ejemplos de bloques anónimos y procedimientos
END;
TEMA 12: INTRODUCCIÓN AL LENGUAJE PL/SQL
4.2. Uso de procedimientos
Ejemplo: Procedimiento PL/SQL sencillo para consultar los datos de un cliente:
SQL> CREATE OR REPLACE PROCEDURE Ver_Cliente (nomcli VARCHAR2)
2 IS
3 NifCli VARCHAR2(10);
4 DomCli VARCHAR2(15);
5 BEGIN
6 SELECT nif, domicilio INTO NifCli, DomCli
7 FROM Clientes WHERE nombre = nomcli;
8 DBMS_OUTPUT.PUT_LINE (‘Nombre: ‘ ||nomcli|| ‘NIF: ‘||
nifcli || ‘Domiclio ‘|| domcli);
9 EXCEPTION
10 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


TEMA 12: INTRODUCCIÓN AL LENGUAJE PL/SQL
9 Si el compilador detecta errores saldrá el siguiente mensaje:
Procedimiento creado con errores de compilación
9 La orden SHOW ERRORS permite ver los errores detectados.

9 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;

9 Podemos insertar comentarios:


- De línea con “--“
- De varias líneas con /* <comentario> */

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


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 BEGIN
6 SELECT precio_uni INTO vPrecio FROM Productos WHERE
Cod_Producto = vCodProd;
7 DBMS_OUTPUT.PUT_LINE (vPrecio);
8 END;
9 /
Procedimiento creado
SQL> EXECUTE Ver_Precio(7);

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


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)
IS
PrecioAnt NUMBER(5);
BEGIN
SELECT 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;
EXCEPTION
WHEN 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


PROGRAMACIÓN EN L4G Y HERRAMIENTAS CASE
TEMA 13: FUNDAMENTOS DEL LENGUAJE PL/SQL

1. TIPOS DE DATOS BÁSICOS


2. IDENTIFICADORES
3. VARIABLES

3.1. DECLARACIÓN E INICIALIZACIÓN DE VARIABLES


3.2. USO DE LOS ATRIBUTOS %TYPE Y%ROWTYPE
3.3. CONSTANTES
3.4. ÁMBITO Y VISIBILIDAD DE LAS VARIABLES

4. OPERADORES
5. FUNCIONES DE SQL
6. SENTENCIA GOTO
7. SUBPROGRAMAS

7.1. PROCEDIMIENTOS
7.2. FUNCIONES
7.3. PARÁMETROS
TEMA 13: FUNDAMENTOS DEL LENGUAJE PL/SQL
1. Tipos de datos básicos

9 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

9 Se utilizan para nombrar los objetos que intervienen en un programa: variables,


constantes, cursores, excepciones, procedimientos, funciones, etiquetas,…

9 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 ( _
).

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

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


TEMA 13: FUNDAMENTOS DEL LENGUAJE PL/SQL

3.1. Declaración e inicialización de variables


9 Las variables deben declararse antes de su uso.
9 Formato: <nombreVariable> <tipo> [NOT NULL] [ { := |
DEFAULT } <valor> ]
9 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 %ROWTYPE


9 Para 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 las
columnas de una tabla o vista de datos.

3.3. Constantes
9 Se pueden declara constantes mediante el siguiente formato:
<nombreVariable> CONSTANT <tipo>:= <valor>

3.4. Ámbito y visibilidad de las variables


9 La 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
TEMA 13: FUNDAMENTOS DEL LENGUAJE PL/SQL

Asignación :=

Lógicos NOT T F NULL


AND AND T F NULL OR T F NULL

T T F NULL T T T T
F T NULL OR
F F F F F T F NULL
NOT NULL NULL F NULL NULL T NULL NULL

Concatenación ||

Comparación = != < > <= >=


IS NULL IS NOT NULL
BETWEEN NOT BETWEEN
LIKE NOT LIKE
IN NOT IN

Aritméticos + - * / **

4. Operadores
TEMA 13: FUNDAMENTOS DEL LENGUAJE PL/SQL

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

9 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.
BEGIN
DBS_OUTPUT.PUT_LINE(TO_CHAR(SYSDATE,’DAY,DD MONTH “ A LAS “YYYY:HH24:MI:SS’));
END;
/
LUNES , 01 ENERO A LAS 2008:01:13:48
Procedimiento PL/SQL terminado con éxito.

9 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
TEMA 13: FUNDAMENTOS DEL LENGUAJE PL/SQL

7.1. Procedimientos
CREATE [OR REPLACE] PROCEDURE nombre [(param [IN | OUT | INOUT] <tipo>) ]
[IS|AS]
BEGIN
<codigo del procedimiento>
[EXCEPTION]
END;
7.2. Funciones
CREATE [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;
9 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í.
9 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
TEMA 13: FUNDAMENTOS DEL LENGUAJE PL/SQL

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

9 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.

9 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
TEMA 13: FUNDAMENTOS DEL LENGUAJE PL/SQL

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

IN 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
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.

IN OUT 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.

7. Subprogramas
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. EXCEPCIONES
6.1. EXCEPCIONES INTERNAS PREDEFINIDAS
6.2. EXCEPCIONES PREDEFINIDAS POR EL USUARIO
TEMA 14: CURSORES Y EXCEPCIONES EN PL/SQL

9 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.

9 En estos casos se manejan los cursores explícitos.

9 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>;

9 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
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 > };

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

9 En este caso, la variable puede ser declarada de esta forma:


<variable > <nombrecursor>%ROWTYPE

9 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 FETCH
recupera 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
TEMA 14: CURSORES Y EXCEPCIONES EN PL/SQL
Ejemplo:
DECLARE
CURSOR C1 IS SELECT NOMBRE, APELLIDO
FROM ARBITRO;
Vnom VARCHAR2(15);
Vapel VARCHAR2 (20;
BEGIN
OPEN C1;
LOOP
FETCH C1 INTO vNom, vApel;
EXIT WHEN C1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE ( vNom || ‘ ‘ || vApel);
END LOOP;
CLOSE C1;
END;

9 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
TEMA 14: CURSORES Y EXCEPCIONES EN PL/SQL
9 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;
BEGIN
OPEN 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; 2. Atributos del cursor
END;
TEMA 14: CURSORES Y EXCEPCIONES EN PL/SQL

Ejemplo:
DECLARE
CURSOR C1 IS SELECT Nombre FROM Futbolista WHERE CodEq= ‘E1’;
Vnom VARCHAR2(15);
BEGIN
OPEN C1;
LOOP
FETCH C1 INTO vNom;
DBMS_OUTPUT.PUT_LINE (C1%ROWCOUNT|| vNom);
EXIT WHEN C1%NOTFOUND;
END LOOP;
CLOSE C1;
END;

9 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


TEMA 14: CURSORES Y EXCEPCIONES EN PL/SQL
9 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 cualquiera


CREATE 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
TEMA 14: CURSORES Y EXCEPCIONES EN PL/SQL

9 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.

9 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.

9 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
TEMA 14: CURSORES Y EXCEPCIONES EN PL/SQL

9 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 Futbolista
WHERE salario > 1800;
BEGIN
FOR vReg IN C2 LOOP
DBMS_OUTPUT.PUT_LINE (vreg.Nombre ||’ – ‘ || vreg.Peso ||’ –
‘ || vreg.Estatura);
END LOOP;
END;
4. Cursor FOR...LOOP
TEMA 14: CURSORES Y EXCEPCIONES EN PL/SQL
9 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.
9 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 INTO
han 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.

9 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


TEMA 14: CURSORES Y EXCEPCIONES EN PL/SQL

9 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


TEMA 14: CURSORES Y EXCEPCIONES EN PL/SQL

Ejemplo:
DECLARE
vDpto Departamentos.Nombre%TYPE;
vLoc Departamentos.Localidad%TYPE;
BEGIN
vDpto := ‘MARKETING’; /* No existe Marketing */
UPDATE Departmentos SET Localidad=’Madrid’ WHERE Nombre= vDpto; /*
Fallará*/
IF SQL%NOTFOUND THEN
DBMS_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 THEN
DBMS_OUTPUT.PUT_LINE (‘Imposible nunca pasará por aquí’);
END IF;
END;

5. Atributos con cursores explícitos


TEMA 14: CURSORES Y EXCEPCIONES EN PL/SQL
9 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 vmax
FROM Emple WHERE NumDpto := VDpto; /* Nunca levantará NO_DATA_FOUND
*/
IF SQL%NOTFOUND THEN /* Nunca sera cierto */
… /* Nunca se ejecutará */
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN …. /* No sera invocado*/
END;

5. Atributos con cursores explícitos


TEMA 14: CURSORES Y EXCEPCIONES EN PL/SQL
9 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 predefinidas


9 Se disparan automáticamente al producirse determinados errores. Las más frecuentes son:
Código error Oracle Valor SQL CODE Excepción Se disparan cuando…
ORA-06530 -6530 ACCESS_INTO_NULL Se intenta acceder a los atributos de
un objeto no inicializado

ORA-06531 -6531 COLLECTION_IS_NULL Se intenta acceder a elementos de


una colección que no ha dio
inicializada

ORA-06511 -6511 CURSOR_ALREADY_OPEN Intentamos abrir un cursor que ya se


encuentra abierto

ORA-00001 -1 DUPVAL_ON_INDEX Se intenta almacenar un valor que


crearía duplicados en la clave
primaria o en una columna con la
restricción UNIQUE

6. Excepciones
TEMA 14: CURSORES Y EXCEPCIONES EN PL/SQL
Código error Oracle Valor SQL CODE Excepción Se disparan cuando…
ORA-01001 -1001 INVALID_CURSOR Se intenta realizar una operación no
permitida sobre un cursor (por
ejemplo, cerrar un cursor que no se
ha abierto)

ORA-01722 -1722 INVALID_NUMBER Fallo al intentar convertir una cadena


a un valor numérico

ORA-01017 -1017 LOGIN_DENIED Se intenta conectar a ORACLE con


un usuario o una clave no válidos

ORA-01012 -1012 NOT_LOGGED_ON Reintenta acceder a la BD sin estar


conectado a Oracle

ORA-01403 +100 NODATA_FOUND

ORA-06501 -6501 PROGRAMA_ERROR Hay un problema interno en la


ejecución del programa

ORA-06504 -6504 ROWTYPE_MISMATCH La variable del cursor del HOST y la


variable del cursor PL/SQL
pertenecen a tipos incompatibles

ORA-06533 -6533 SUBSCRIPT_OUTSIDE_LIMT Se intenta acceder a una tabla


anidada o a un array con un valor de
índice ilegal (por ejemplo, negativo)

ORA-06500 -6500 STORAGE_ERROR El bloque PL/SQL se ejecuta fuera de


memoria (o hay algún otro error de
memoria).

ORA-00051 -51 TIMEOUT_ON_RESOURCE Se excede el tiempo de espera para


un recurso.

6. Excepciones
TEMA 14: CURSORES Y EXCEPCIONES EN PL/SQL
Código error Oracle Valor SQL CODE Excepción Se disparan cuando…
ORA-01422 -1422 TO_MANY_ROWS

ORA-06502 -6502 VALUE_ERROR Un error de tipo aritmético, de


conversión, de truncamiento,…

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

9 No hay que declararlas en la sección DECLARE

6.2. Excepciones definidas por el usuario


9 Para 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
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;
BEGIN
SELECT 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;
EXCEPTION
WHEN 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
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


TEMA 15: TRIGGERS EN PL/SQL
9 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).

9 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
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>;

9 El uso de OR REPLACE permite sobrescribir un trigger existente. Si se omite, y el trigger


existe, se producirá, un error.
9 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.
9 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 ROW
indica 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
TEMA 15: TRIGGERS EN PL/SQL
Ejemplo: Crear el trigger audit_subida_salario que se disparará después de cada modificación
de la columna de la tabla EMPLE:

CREATE OR REPLACE TRIGGER AUDIT_SUBIDA_SALARIO


AFTER UPDATE OF SALARIO ON EMPLE
FOR EACH ROW
BEGIN
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 tabla
AUDITARAEMPLE:

CREATE OR REPLACE TRIGGER audit_borrado_emple


BEFORE DELETE ON emple
FOR EACH ROW
BEGIN
INSERT INTO auditaraemple VALUES (‘BORRADO EMPLEADO ’||’*’||:OLD.emp_no
|| ‘*’||:OLD.apellido || ‘*’||:OLD.dept_no);
END;
2. Declaración de triggers
TEMA 15: TRIGGERS EN PL/SQL
La siguiente tabla resume los contenidos anteriores.
Valor Descripción
INSERT, DELETE, UPDATE Define qué tipo de orden DML (INSERT, DELETE o
UPDATE) provoca la activación del disparador.

BEFORE , AFTER Define si el disparador se activa antes o después de que se


ejecute la orden.

FOR EACH ROW 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 STATEMENT Se asume por omisión.

2. Declaración de triggers
TEMA 15: TRIGGERS EN PL/SQL
9 La cláusula WHEN sólo es válida para los disparadores con nivel de fila.
9 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 vez


que insertamos un nuevo registro en la tabla PRODUCTOS:

CREATE OR REPLACE TRIGGER tr_PRODUCTOS


AFTER INSERT ON PRODUCTOS
FOR EACH ROW
BEGIN
INSERT 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
TEMA 15: TRIGGERS EN PL/SQL
9 Una misma tabla puede tener varios triggers. En tal caso es necesario
conocer el orden en el que se van a ejecutar.

9 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


TEMA 15: TRIGGERS EN PL/SQL
9 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


TEMA 15: TRIGGERS EN PL/SQL
9 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.
9 Utilizando esta variable podemos acceder a los datos que se están
insertando, actualizando o borrando.
9 La siguiente tabla muestra los valores de OLD y NEW.
ACCION SQL OLD NEW

INSERT No definido; todos los campos toman Valores que serán insertados
valor NULL. cuando se complete la orden.

UPDATE Valores originales de la fila, antes de Nuevos valores que serán escritos
la actualización. cuando se complete la orden.

DELETE Valores, antes del borrado de la fila. No definidos; todos los campos
toman el valor NULL.

9Los registros OLD y NEW son sólo válidos dentro de los disparadores con nivel
de fila.
5. Utilización de :OLD y :NEW
TEMA 15: TRIGGERS EN PL/SQL
9 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.

9 Su comportamiento es el siguiente:

PREDICADO COMPORTAMIENTO

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


caso.

UPDATING TRUE si la orden de disparo es UPDATE; FALSE en


otro caso.

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


caso.

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


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_emple


INSTEAD OF DELETE OR INSERT OR UPDATE ON EMPLEAD
FOR EACH ROW
DECLARE
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;
ELSE
RAISE_APPLICATION_ERROR(-20500,'Error en la actualización');
END IF;
END;
6. Utilización de los predicados INSERTING, UPDATING Y DELETING

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