Vous êtes sur la page 1sur 70

Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

1.- VISIN GENERAL DE PL/SQL

1.1. Introduccin al lenguaje PL/SQL.


1.2. Entornos de desarrollo.

1.1. - INTRODUCCIN AL LENGUAJE PL/SQL

El PL/SQL es un lenguaje de bases de datos para realizar programas que incluyan


sentencias de SQL. Estos programas se denominan bloques y se clasifican en:

-Annimos: No suelen ser reutilizables. No llevan ningn tipo de nombre. Son


semejantes a cualquier programa de 3 Generacin.

-Subprogramas o bloques con nombre: Suelen tener parmetros y pueden ser


invocados por otro bloque. Existen 2 tipos de subprogramas:

Funciones: Se utilizan para calcular un valor.


Procedimientos: Ejecutan una serie de acciones.

Los beneficios que presentan los subprogramas son los siguientes:

- Mejorar el mantenimiento.
- Mejorar la seguridad e integridad de los datos.
- Mejorar el rendimiento.

1.2. - ENTORNOS DE DESARROLLO

Los dos principales entornos de desarrollo de PL/SQL son los siguientes:

SQL*PLUS: que es el mismo entorno que hemos utilizado para SQL.

ORACLE DEVELOPER PROCEDURE BUILDER: es una herramienta que podemos


utilizar para crear, ejecutar y depurar las unidades de programa PL/SQL utilizadas
en nuestras herramientas de la aplicacin, o sobre Oracle Server a travs de su
interfaz grfica.

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 1. 1


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

2. DECLARACIN DE VARIABLES

2.1.- Introduccin.
2.2.- Uso de variables en PL/SQL.
2.3.- Tipos de variables.

2.1.- INTRODUCCIN

La estructura de un bloque annimo de PL es la siguiente:

[DECLARE] Opcional

Variables, cursores y excepciones


definidas por el usuario.

BEGIN Obligatorio

Sentencias SQL.
Sentencias de control PL/SQL.

[EXCEPTION] Opcional

Acciones a realizar cuando se


producen errores.

END; - Obligatorio

Estos bloques se suelen almacenar en scripts, al igual que los informes, para luego
ejecutarlos. Un bloque PL se puede dividir en bloques lgicos o declarativos (declare),
ejecutables (begin) y de excepciones (exception):

1 Seccin Declarativa

Contiene todas las variables, constantes, y excepciones definidas por el usuario a


las que hace referencia en las secciones ejecutables y excepciones.

2 Seccin Ejecutable

Contiene sentencias SQL para manipular datos de la BD y sentencias PL/SQL para


manipular datos del bloque.

3 Seccin para Gestin de Excepciones

Especifica las acciones que se han de ejecutar cuando aparecen errores y


condiciones anormales de la seccin ejecutable.

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 2. 1


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

La ejecucin de sentencias y bloques desde SQL*PLUS se har de la siguiente forma:

- Colocar ; al final de una sentencia SQL*PLUS o de una sentencia de control PL/SQL.


- Colocar / al ejecutar un bloque annimo en el buffer.
- Colocar . para cerrar el buffer de SQL*PLUS.

Tipos de Bloques PL/SQL.

ANNIMOS SUBPROGRAMAS

[DECLARE] FUNCIONES PROCEDIMIENTOS


... FUNCTION nb_func PROCEDURE nb_pro
BEGIN RETURN data_type IS
... IS ...
[EXCEPTION] BEGIN BEGIN
... ... ...
END; RETURN VALUE; [EXCEPTION]
[EXCEPTION] ...
... END;
END;

- Bloques annimos: son bloques sin nombrar. Son declarados en una aplicacin en la que
se van a ejecutar y se transfieren al motor PL/SQL para que se ejecuten al momento.
- Subprogramas: son bloques PL/SQL especificados que pueden tomar parmetros y
pueden ser invocados. Puede declararlos como procedimientos o como funciones.
Generalmente se usan los procedimientos para ejecutar una accin y una funcin para
calcular un valor.

2.2.- USO DE VARIABLES EN PL/SQL

Las variables se utilizan para:

Almacenamiento de forma temporal de datos.


Manipulacin de valores almacenados.
Reusabilidad.
Fcil mantenimiento.

La gestin de variables en PL/SQL presentan los siguientes aspectos:

Las variables se declaran e inicializan dentro de la seccin de declaracin.


Asignar nuevos valores a las variables dentro de la seccin de cdigos.
Pasar valores a los bloques PL/SQL a travs de parmetros.
Ver los resultados a travs de las variables de salida.

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 2. 2


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

Las variables se clasifican en:

Variables PL/SQL:

Escalares: Contienen un valor nico. Los principales tipos de datos son los
que corresponden a tipos de columnas en las tablas del servidor Oracle8;
PL/SQL tambin soporta variables booleanas.
Compuestas: Hacen referencia a tipos de datos compuestos, como los
registros y las tablas.
Referenciada: o punteros, que designan otros artculos del programa.
LOB: Especifican imgenes o cualquier conjunto de caracteres o bytes que
tengan una longitud excesiva.

Variables no PL/SQL: Su misin es transferir informacin desde el puesto al


servidor.

Enlace o Bind.
Host.

Todas ellas tienen un tipo de datos que se especifica en un formato de


almacenamiento, restricciones, y rango de valores.

Sintaxis:

Nb_variable [CONSTANT] data_type [NOT NULL]


[:= expr | DEFAULT expr ];

Dnde:

CONSTANT: restringe la variable para que no pueda cambiar de valor. Las


constantes deben inicializarse.

DATA_TYPE: Es un tipo de datos escalar, compuesto o LOB.

NOT NULL: restringe la variable. La obliga a contener algn valor. Las NOT NULL
tambin se deben inicializar.

EXPR: Cualquier expresin PL/SQL, pudiendo ser un literal, otra variable, etc.

Ejemplos:

V_HIREDATE NUMBER(2) NOT NULL:=10;


V_HIREDATE DATE;
V_LOC VARCHAR2(30):=ATLANTA;
C_COMM CONSTANT NUMBER(4):=10;

Recomendaciones a seguir

1 Intentar poner los identificadores: V variable, C constante, G global.


2 Inicializar las constantes y las variables NOT NULL.

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 2. 3


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

3 Inicializar los identificadores con := DEFAULT.


4 Declarar como mximo un identificador por lnea.

Reglas para los nombres

- Dos variables pueden tener el mismo nombre si estn en dos bloques diferentes.
- El nombre de la variable (identificador) no debe ser el mismo que el de una
columna de una tabla utilizada en el bloque.
- Se puede asignar cualquier valor a una variable simplemente nb_var:=expresion;
- Se pueden usar las funciones TO_NUMBER, TO_DATE y TO_CHAR.

Funciones para imprimir y ver la ejecucin de bloques

Para poder imprimir frases en pantalla no existen funciones especficas, pero se


debe usar:

DBMS_OUTPUT.PUT_LINE(<expresion>);

Para poder ver la ejecucin:

SET SERVEROUTPUT ON

Ejemplo 2:

DECLARE
V_TEXTO VARCHAR2(20):=HOLA MUNDO;
BEGIN
DBMS_OUTPUT.PUT_LINE(V_TEXTO);
END;
/

EL ATRIBUTO %TYPE:

Se utiliza la mayora de las veces cuando el valor almacenado en la variable se


deriva de una columna de la tabla de la BD. Adems se utiliza si se hace referencia a una
variable declarada previamente.

Ejemplo

v_ename emp.ename%TYPE;
v_ename adopta el tipo de dato de emp.ename.

v_balance number(7,2);
v_balance se le asigna el tipo number de 7,2

v_min_val v_balance%TYPE;
v_min_val adopta el tipo number(7,2) como v_balance

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 2. 4


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

2.3.- TIPOS DE VARIABLES

VARIABLES PL/SQL

Variables escalares:

Las principales son:

Tipos Descripcin
VARCHAR2(n) Para datos tipo carcter de longitud 3270 bytes.
NUMBER[(p,s)] Enteros y decimales.
DATE Fechas y horas.
CHAR(n) Cadenas de longitud fija.
LONG Datos carcter de longitud variable.
LONG RAW Datos binarios y cadenas.
BOOLEAN Utilizada para clculos lgicos, admite TRUE, FALSE y NULL.
Slo pueden estar conectadas por los operadores lgicos
AND, NOT, OR y las expresiones aritmticas de carcter y
fecha que pueden devolver un valor booleano.
BINARY_INTEGER Tipo de base de enteros entre 2147483647 y 2147483647.

Variables de datos compuestos:

Existen fundamentalmente 2 tipos de datos:

- Registros: trata datos relacionados pero no iguales como una unidad lgica.
- Tablas: hacen referencia a colecciones de datos que permiten ser manipulados.

Variables LOB:

Almacenan gran cantidad de datos no estructurados. Las ms importantes son:

- CLOB: Almacenan grandes bloques de caracteres.


- BLOB: Almacenan objetos binarios grandes en la B.D.
- BFILE: Almacenan objetos binarios grandes en archivos del sistema.
- NCLOB: Almacenan bloques grandes de datos de longitud fija.

VARIABLES NO PL/SQL

Variables de enlace bind:

Es una variable que declara cualquier usuario y es utilizada despus para transferir
valores bien sean numricos o de caracteres dentro o fuera de uno o ms programas PL.

Host:

Tienen el mismo funcionamiento a las de enlace con la diferencia que a la hora de


definirlas hay que precederlas de 2 puntos (:HOST).

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 2. 5


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

3 - SENTENCIAS EJECUTABLES

3.1 Sintaxis y directrices de bloque.


3.2 Cdigo de comentarios.
3.3 Operadores.
3.4 Funciones.
3.5 Bloques anidados y mbito de las variables.
3.6 Directrices de programacin.

3.1 SINTAXIS Y DIRECTRICES DE BLOQUE

- Una sentencia puede terminar en una lnea y continuar en la otra si ponemos al final de
toda la sentencia un punto y coma;

- Los identificadores, literales, comentarios, etc. pueden separarse por uno o ms


espacios.

- Los identificadores sirven para dar nombre a las unidades y artculos de los programas
PL/SQL. Pueden contener hasta 30 caracteres, no pueden contener palabras
reservadas, deben comenzar por una letra y el nombre de un identificador no es
aconsejable que coincida con el nombre de una columna de una tabla.

- Sintaxis y directrices de los literales: Los nmeros pueden ser simples o ir dentro de
una notacin cientfica. Han de ir entre comillas las fechas y las cadenas.

3.2 CDIGO DE COMENTARIOS

Si el comentario ocupa una lnea se comienza poniendo -- comentario. Si ocupa


varias lneas ponemos /* al abrirlo y para cerrarlo */

3.3 OPERADORES

Operadores por orden de operacin. Operacin


** , NOT Exponenciacin, negacin lgica.
+,- Identidad y negacin.
*,/ Multiplicacin y divisin.
+ , - , || Suma, resta y concatenacin.
= , != , < , >, <= , >= , Comparacin.
IS NULL, LIKE, BETWEEN, IN
AND Conjuncin.
OR Inclusin.

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 3. 1


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

3.4 - FUNCIONES

ARITMTICAS: Devuelven un nmero:

Funciones Descripcin
ABS(n) Devuelve el valor absoluto de un nmero.
CEIL(n) Devuelve el entero ms pequeo o igual al nmero.
COS(n) Coseno de n.
EXP(n) Nmero e elevado a n.
FLOOR(n) Entero ms grande o igual a n.
LN(n) Devuelve el logaritmo neperiano de n.
LOG(n1,n2) Logaritmo en base n1 de n2.
MOD(n1,n2) Devuelve el resto de dividir n1 entre n2.
POWER(n1,n2) Devuelve n1 elevado a n2.
ROUND(n1,n2) Redondea n1 con n2 decimales.
SVGN(n) Devuelve 1 si el nmero es menor de 0, 0 si es igual a 0 y 1 si es
mayor de 0.
SIN(n) Seno de n.
SQRT(n) Raz cuadrada de n, que ha de ser siempre mayor de 0.
TAN(n) Tangente de n.
TRUNC(n1,n2) Trunca n1 con n2 decimales.

CARCTER: Devuelven cadenas de caracteres.

Funciones Descripcin
ASCII(C) Devuelve el ASCII del carcter.
CHR(n) Devuelve el carcter correspondiente al nmero n.
CONCAT (c1, c2) Concatena 2 cadenas.
INITCAP(c) Transforma la primera letra a mayscula.
LENGHT(c) Longitud de la cadena.
LOWER(c) Transforma a minsculas.
LPAD (c1, n, c2) Justifica a la derecha el valor del carcter c1 n posiciones y los
blancos los reemplaza por el carcter c2.
LTRIM(c1, c2) Suprime caracteres a la izquierda hasta el primer carcter que
no est en c2. Si se omite c2 lo pone todo en blanco.
REPLACE(c1,c2,c3) Devuelve c1 con la cadena c2, reemplazada por c3 y as
sucesivamente.
RPAD(c1,n,c2) Iguala a la derecha.
RTRIM(c1,c2) Igual que LTRIM pero por la derecha.
SUBSTR(c1,m,n) Substrae de la cadena c1, y desde el carcter m, n caracteres.
TRANSLATE(c1,c2,c3) Devuelve la cadena c1 con cada carcter de c2 que contenga
reemplazado por el carcter de c3 con el que se corresponda.
UPPER(c) Convierte c a maysculas.

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 3. 2


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

CONVERSIN

Funciones Descripcin
TO_CHAR(c1,fmt) Convierte un nmero o fecha a cadena de caracteres.
TO_DATE(c1,fmt) Convierte una cadena de caracteres a un nmero.
TO_NUMBER(c1,fmt) Convierte una cadena de caracteres a una fecha.

FECHA

Funciones Descripcin
ADD_MONTH(fecha,n) Agrega meses a una fecha.
LAST_DAY(fecha) ltimo da del mes.
MONTHS_BETWEEN(fecha1,fecha2) Nmero de meses entre dos fechas.
NEXT_DAY(fecha, caracter) Prximo da de la fecha especificada.

DIVERSAS

Funciones Descripcin
DUMP(expr) Devuelve la expresin en el formato interno de Oracle.
GREATEST(lista de valores) Da como resultado el valor ms grande de la lista.
LEAST (lista de valores) Da como resultado el valor ms pequeo de la lista.
NVL(expr1, expr2) Reemplaza los nulos por otro valor.
USER Devuelve al usuario conectado.
USERENV(opcin) Devuelve informacin sobre el usuario. Las opciones
pueden ser:
SESSIONID: Se identifica la sesin.
TERMINAL: Identificador del terminal.
LANGUAGE: Lenguaje activo.
DECODE Realiza la funcin de IF/THEN/ELSE.

3.5 - BLOQUES ANIDADOS

Tambin se pueden anidar bloques de forma que las variables tengan su propio
mbito de ejecucin:

DECLARE
X BINARY_INTEGER;
BEGIN

DECLARE
Y BINARY_INTEGER;
BEGIN
...............
EXCEPTION
.........
END;

EXCEPTION
.......
END;

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 3. 3


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

Las sentencias pueden ser anidadas cuando el bloque PL/SQL lo requiera. Un bloque
anidado se convierte en una sentencia. La seccin de excepciones tambin puede contener
bloques, pero generalmente el lugar donde se suele trabajar es en la zona ejecutable. El
mbito de un objeto es la regin de programa que hace referencia a dicho objeto.

Las variables tienen como mbito su propio bloque. En este caso, la variable Y slo
ser reconocida por el segundo bloque, y una vez finalizado este el bloque principal no la
reconocer, por el contrario, la variable X tiene como mbito todo el bloque, ya que tiene
vigencia en su propio bloque y en el bloque anidado, ya que este pertenece al bloque
principal.

3.6 DIRECTRICES DE PROGRAMACIN

Para hacer un bloque PL/SQL Oracle marca las siguientes directrices:

- Documentar el cdigo con comentarios.

- Utilizar maysculas para sentencias SQL*PLUS, para palabras claves de PL/SQL y para
los tipos de datos y minsculas para identificadores, parmetros, columnas y tablas de
la BD.

- Desarrollar convenciones de nomenclatura para los identificadores y otros objetos,


evitando ambigedades en los nombres. As pues la variable se define como V_, la
constante C_, el cursor Nombre_cursor, la excepcin como E_, etc.

- Sangrar los bloques para obtener mayor claridad en el cdigo.

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 3. 4


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

4.- INTERACCIN CON EL SERVIDOR ORACLE

4.1 Sentencias SQL*PLUS en PL/SQL.


4.2 La sentencia SELECT en PL/SQL.
4.3 Las sentencias DML en PL/SQL.
4.4 Conversiones de nomenclatura.
4.5 COMMIT y ROLLBACK.
4.6 Cursores SQL.

4.1 SENTENCIAS SQL*PLUS EN PL/SQL

Cualquier sentencia SQL, salvo excepciones, es aplicable a sentencias PL/SQL. La


sentencia SELECT en PL/SQL cambia su formato incluyendo la palabra reservada INTO.

Las sentencias DML incluidas COMMIT, ROLLBACK y SAVEPOINT tienen idntico


formato que en SQL*PLUS.

No soporta sentencias DDL o lenguaje de definicin de datos (CREATE, DROP etc.),


ni sentencias DCL o lenguaje de control de datos (GRANT, REVOKE etc.).

Cuando iniciemos una nueva sesin conviene escribir lo siguiente:

SET SERVEROUTPUT ON: Muestra los errores de un bloque PL/SQL.


SET VERIFY OFF: Elimina las variables de sustitucin.

Si no se quiere escribirlas cada vez que iniciemos una nueva sesin se pueden
escribir en el fichero LOGIN.SQL.

4.2 LA SENTENCIA SELECT EN PL/SQL

Esta sentencia sirve para recuperar datos de tablas, tal y como haca en
SQL*PLUS.

Sintaxis:

SELECT lista_seleccionada
INTO {nb_variable1 [ , nb_variable2 ] | nb_registro}
FROM nb_tabla
WHERE condicin;

Ejemplo 1:

Obtener un bloque PL que calcule la suma de los salarios de la tabla EMP


visualizando su resultado.

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 4. 1


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

DECLARE
V_TOTAL NUMBER;
BEGIN
SELECT SUM(SAL) INTO V_TOTAL FROM EMP;
DBMS_OUTPUT.PUT_LINE(V_TOTAL);
END;
/

Ejemplo 2:

Obtener un bloque PL que visualice el cdigo de departamento y la localidad de la


tabla DEPT del departamento SALES.

DECLARE
V_DEPTNO NUMBER(2);
V_LOC VARCHAR2(15);
BEGIN
SELECT DEPTNO, LOC INTO V_DEPTNO, V_LOC
FROM DEPT
WHERE DNAME=SALES;
DBMS_OUTPUT.PUT_LINE(V_DEPTNO);
DBMS_OUTPUT.PUT_LINE(V_LOC);
END;
/

4.3 LAS SENTENCIAS DML EN PL/SQL

Tienen el mismo formato que las sentencias DML de SQL*PLUS

Ejemplo 1:

Insertar en la tabla DEPT un departamento de nombre PUBLICIDAD que est en


MADRID asignado directamente el cdigo en una variable a travs de la pseudocolumna
NEXVAL.

DECLARE
V_DEPTNO DEPT.DEPTNO%TYPE;
BEGIN
SELECT DEPTNO_SEQUENCE.NEXTVAL INTO V_DEPTNO
FROM DUAL;
INSERT INTO DEPT(DEPTNO, DNAME, LOC)
VALUES (V_DEPTNO,'PUBLICIDAD, MADRID);
END;
/

Ejemplo 2:

Suprimir el registro insertado anteriormente:

DECLARE
V_DEPTNO DEPT.DEPTNO%TYPE:= 50;
BEGIN
DELETE FROM DEPT WHERE DEPTNO= V_DEPTNO;
END;
/

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 4. 2


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

4.4 CONVENCIONES DE NOMENCLATURA

Los identificadores y las columnas de la BD deben tener nombres distintos para


evitar ambigedades en la clusula WHERE.

Los errores de sintaxis pueden surgir porque PL/SQL comprueba primero el nombre
de la variable PL/SQL y luego el de la tabla.

4.5 COMMIT Y ROLLBACK

Los comandos COMMIT y ROLLBACK se pueden introducir dentro de los bloques


PL/SQL siempre y cuando se utilicen sentencias DML. Es conveniente utilizar estos
comandos o bien al principio del bloque, lo cual permitir validar los bloques ejecutados
hasta ese instante o ponerlos al final para validar el bloque que se est ejecutando.

Estos comandos funcionan de forma idntica a SQL*PLUS. Muchos programadores


de PL/SQL no suelen incluirlos en los bloques, y lo ejecutan fuera del bloque, una vez
terminado el trabajo.

4.6 CURSORES SQL

Cada vez que se crea una sentencia SQL el servidor Oracle abre un rea de
memoria en la que se analiza y ejecuta el comando. Este rea de memoria es lo que se
conoce con el nombre de cursor. Un cursor es un rea de trabajo privada de SQL. Pueden
ser de los siguientes tipos:

IMPLCITOS: Son los que ya tiene el servidor Oracle. Los utiliza el servidor para
analizar y ejecutar las sentencias SQL son:

Tipos Descripcin
SQL%ROWCOUNT Cuenta el nmero de filas afectadas por la
sentencia SQL ms reciente. Sirve para que nos
cuente el nmero de filas que hemos leido del
cursor.
SQL%FOUND Atributo booleano que da como resultado TRUE si la
sentencia SQL afecta a alguna fila. Sirve para saber
si el cursor tiene ms datos o por el contrario ya los
ha ledo todos.
SQL%NOTFOUND Igual que el anterior pero da TRUE si la sentencia
SQL no afecta a ninguna fila.
SQL%ISOPEN Siempre es FALSE porque SQL cierra los cursores
implcitos inmediatamente despus de ejecutarlos.

EXPLCITOS: Son declarados por el programador.

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 4. 3


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

Ejemplo:

Suprimir de la tabla DEPT aquellos departamentos que tengan un cdigo mayor de


30. Se utilizar el cursor ROWCOUNT.

DECLARE
V_ELIMI NUMBER:=30;
BEGIN
DELETE DEPT WHERE DEPTNO>V_ELIMI;
DBMS_OUTPUT.PUT_LINE(SQL%ROWCOUNT|| FILAS ELIMINADAS);
END;
/

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 4. 4


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

5 ESTRUCTURAS DE CONTROL

5.1 Introduccin.
5.2 Control condicional IF.
5.3 Estructuras repetitivas.

5.1 INTRODUCCIN

Como cualquier lenguaje procedural, PL/SQL dispone de una serie de rdenes que
nos permiten establecer controles y condiciones a los programas, pudindose por tanto
representarlos mediante operaciones secuenciales, selectivas y repetitivas. Las dos ltimas
se apoyan en condiciones para establecer su comportamiento.

5.2 CONTROL CONDICIONAL IF

Nos permite seleccionar unas determinadas rdenes a ejecutarse dependiendo de


una condicin.

La sintaxis de la condicional simple IF-THEN sera como sigue a continuacin:

IF condicin THEN
rdenes;
END IF;

Las ordenes se ejecutaran en el caso de que la condicin fuera verdadera, si por el


contrario fueran falsas o devolviera un valor NULL entonces no se realizaran.

Ejemplo 1:

IF V_MATRI<12000 THEN
UPDATE ALUMNOS
SET MATRCULA=12500
WHERE COD=10;
END IF;

La sintaxis para una condicional doble del tipo IF-THEN-ELSE sera la siguiente:

IF condicin THEN
rdenes;
ELSE
rdenes;
END IF;

Si la condicin es falsa o NULL, entonces se ejecutan las ordenes que siguen a


ELSE, en caso de ser verdaderas las que estn dentro de THEN.

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 5. 1


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

Ejemplo 2:

Si en la variable renta tenemos una cantidad, que es el total de las matriculas del
curso 3, podramos montar una estructura como esta para saber si el rentable o no
suponiendo que la rentabilidad est por encima del milln de Ptas.


SELECT SUM(MATRICULA) INTO RENTA
FROM ALUMNOS
WHERE CODIGO_CURSO=3;
IF RENTA > 1000000 THEN
INSERT INTO TEMP(COL3) VALUES (RENTABLE);
ELSE
INSERT INTO TEMP(COL3) VALUES (NO RENTABLE);
END IF;

Cuando sea posible, se utilizar la clusula ELSIF en lugar de anidar tantas veces
las sentencia IF. El cdigo es ms fcil de leer y de entender y la lgica est claramente
definida. Si la accin de la clusula ELSE nicamente consiste en otra sentencia IF, es
preferible utilizar la sentencia ELSIF.

Sintaxis:

IF condicin THEN
rdenes;
ELSIF condicin2 THEN
rdenes;
ELSE
rdenes;
END IF;

5.3 - ESTRUCTURAS REPETITIVAS

PL/SQL proporciona prestaciones para estructurar bucles y as repetir varias veces


una sentencia o un conjunto de stas.

Los bucles pueden ser de 3 tipos:

LOOP BSICO.
WHILE.
FOR.

BUCLE LOOP

Proporciona acciones repetitivas sin condiciones globales y requiere la sentencia


EXIT para finalizar el bucle. Si se omite dicha clusula dara lugar a un bucle infinito.

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 5. 2


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

Sintaxis:

LOOP
rdenes;
EXIT [WHEN condicin];
END LOOP;

Ejemplo 1:

Insertar en la tabla ITEM, diez registros, se saldr del bucle cuando se hayan
insertado esos registros.

...
LOOP
INSERT INTO ITEM(ORDER, ITEMID) VALUES (V_ORDER, V_ITEMID);
V_COUNTER:=V_COUNTER+1;
EXIT WHEN V_COUNTER>10;
END LOOP;

BUCLE WHILE

Nos permite asociar una determinada condicin a la hora de ejecutar una serie de
comandos. Se utiliza WHILE mientras la condicin sea cierta.

Sintaxis:

WHILE condicin LOOP


rdenes;
END LOOP;

Ejemplo 2:

Disear un bucle WHILE que sume uno a una variable, mientras que esta sea menor
o igual que 100.


WHILE V_X<=100 LOOP
V_X:=V_X+1;
END LOOP;

BUCLE FOR

Ejecuta las rdenes un nmero predeterminado de veces segn la condicin que va


declarada. Las directrices para la construccin de FOR son:

Hacer referencia al ndice o variable dentro del bucle ya que no se define en


DECLARE.
Utilizar una expresin para hacer referencia al valor actual del ndice.

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 5. 3


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

No hacer referencia al ndice o variable como objetivo de una asignacin.

Sintaxis:

FOR indice IN [REVERSE]


limite_inferior . . limite_superior LOOP
rdenes;
END LOOP;

Ejemplo 3:

Insertar las 10 primeras lneas del pedido nmero 101.

...
V_ORDID ITEM.ORDID%TYPE := 101;
BEGIN

FOR I IN 1..10 LOOP
INSERT INTO ITEM(ORDID, ITEMID)
VALUES (V_ORDID,I);
END LOOP;

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 5. 4


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

6. REGISTROS Y TABLAS:

6.1.- Introduccin.
6.2.- Registros.
6.3.- Atributo %ROWTYPE.
6.4.- Tablas.

6.1.- INTRODUCCIN

Los tipos de datos compuestos son:

Registro: grupo de elementos almacenados en campos, cada uno con su propio


nombre y tipo de datos. Se utiliza para tratar datos relacionados pero
distintos, como una unidad lgica.
Tablas: contienen una columna y una clave primaria (ndice), para dar acceso de
tipo vector a determinadas filas. Se utiliza para hacer referencia y manipular
las colecciones de datos como un objeto completo.

6.2.- REGISTROS

Los registros presentan las siguientes caractersticas:

Los registros deben contener una o ms componentes llamados campos.


Son similares en estructura a los registros de 3 generacin.
No es lo mismo que la fila de una tabla.
Tratan una coleccin de campos como unidad lgica.
Son adecuados para recuperar una fila de datos de una tabla.
Se declaran en la zona declare.

Sintaxis:

TYPE nb_tipo_reg IS RECORD


(field_declaration [ , field_declaration] );

nb_reg nb_tipo_reg;

Donde field_declaration tienen la siguiente estructura:

Nb_campo {tip_dato_campo|variable%TYPE|tabla.column%TYPE|tabla%ROWTYPE}
[[NOT NULL]{:= | DEFAULT} expr ]

Donde:

NB_TIPO_REG: es el nombre del tipo de registro.


NB_REG: es el nombre del registro.
NB_CAMPO: nombre del campo que est dentro del registro.
TIPO_DATO_CAMPO: tipo de dato de un campo.
EXPR: valor inicial.

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 6 . 1


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

Ejemplo 1:

Inicializar un registro ALUMNO con los siguientes valores nombre, nmero de


matricula y cdigo en la zona declarativa.

TYPE REG_ALUMNO IS RECORD


(NOM_ ALUMNO VARCHAR2(25)
NUM_MATRI NUMBER(7,2),
CODIGO NUMBER(3));

ALUMNO REG_ALUMNO;

Ejemplo 2:

Inicializar un registro DEPARTAMENTO con el cdigo de departamento en la zona


declarativa.

TYPE REG_DEPT IS RECORD


(DEPTNO DEPT.DEPTNO%TYPE);

DEPARTAMENTO REG_DEPT;

Ejemplo 3:

Crear un bloque PL/SQL que mediante un cursor seleccione de la tabla DEPT el


campo DEPTNO y DNAME, lo cargue en un registro y visualice los campos del registro
posteriormente. Se introducir un valor por teclado que indicar el nmero de filas del
cursor que se deben ir cargando en el registro y visualizando. El orden de salida ser de
menor a mayor.

DECLARE
CURSOR C1 IS
SELECT DEPTNO, DNAME
FROM DEPT
ORDER BY DEPTNO;

TYPE REGISTRO IS RECORD


(DEPTNO DEPT.DEPTNO%TYPE,
DNAME DEPT.DNAME%TYPE);

REG REGISTRO;

V_NUM NUMBER:=&NUMERO_FILA;

BEGIN
OPEN C1;
FETCH C1 INTO REG;
WHILE (C1%ROWCOUNT<=V_NUM) AND (C1%FOUND)LOOP
DBMS_OUTPUT.PUT_LINE (REG.DEPTNO || ||REG.DNAME);
FETCH C1 INTO REG;
END LOOP;
CLOSE C1;
END;
/

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 6. 2


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

6.3.- ATRIBUTO %ROWTYPE

Para declarar un registro basndose en una coleccin de columnas de una tabla o


vista o cursor se utiliza al atributo %ROWTYPE

Los campos del registro tomarn automticamente sus nombres y tipos de datos de
la columna de la tabla, vista o cursor. El registro almacena por tanto, una fila entera de los
elementos.

Sintaxis:

Nb_registro objeto_referenciado%ROWTYPE;

Ventajas del atributo %ROWTYPE

El nmero y tipo de datos de las columnas de la base de datos pueden no ser


conocidos.
El nmero y tipos de datos de las columnas de la base de datos pueden cambiar
en el momento de la ejecucin.
Es til para recuperar una fila con la sentencia SELECT.

Ejemplo:

Realizar el bloque anterior utilizando todos los campos de la tabla y el atributo


%ROWTYPE:

DECLARE
CURSOR C1 IS
SELECT * FROM DEPT
ORDER BY DEPTNO;

REG C1%ROWTYPE;

V_NUM NUMBER:= &NMERO_FILAS;

BEGIN
OPEN C1;
FETCH C1 INTO REG;
WHILE (C1%ROWCOUNT <= V_NUM) AND (C1%FOUND) LOOP
DBMS_OUTPUT.PUT_LINE (REG.DEPTNO|| ||REG.DNAME||
||REG.LOC);
FETCH C1 INTO REG;
END LOOP;
CLOSE C1;
END;
/

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 6 . 3


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

6.4.- TABLAS (Vectores).

Las tablas presentan las siguientes caractersticas:

Las tablas cuentan con dos componentes fundamentales:

1. Tipos de datos de clave primaria (o ndice) que se declara con el


formato BINARY_INTEGER.
2. Una columna de tipos de datos escalares o de registro que almacena
los elementos de la tabla PL/SQL.

Aumentan dinmicamente porque no tienen restricciones.

Sintaxis:

TYPE nb_tipo_tabla IS TABLE OF


{tipo_columna | variable%TYPE | tabla.columna%TYPE} [NOT NULL] INDEX BY
BINARY_ INTEGER;

nb_tabla nb_tipo_tabla;

Ejemplo:

Mostrar de forma ascendente salarios y nombres de los empleados mediante un


cursor. Almacenando estos en una variable, para posteriormente visualizarlos en dos
tablas, despus se visualizarn los datos que estn cargados en la tabla. El nmero de datos
que se cargarn en las tablas dependern de una variable de sustitucin.

DECLARE

CURSOR C1 IS
SELECT ENAME, SAL FROM EMP
ORDER BY SAL;

TYPE ENAME_TABLA IS TABLE OF


EMP.ENAME%TYPE
INDEX BY BINARY_INTEGER;
E_TABLA ENAME_TABLA;

TYPE SAL_TABLA IS TABLE OF


EMP.SAL%TYPE
INDEX BY BINARY_INTEGER;
S_TABLA SAL_TABLA;

V_ENAME EMP.ENAME%TYPE;
V_SAL EMP.SAL%TYPE;
I BINARY_INTEGER:=0;
V_NUM NUMBER:=&NUM_FILAS;

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 6. 4


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

BEGIN
OPEN C1;
FETCH C1 INTO V_ENAME, V_SAL;
WHILE (C1%ROWCOUNT <= V_NUM) AND (C1%FOUND) LOOP
I:= I+1;
E_TABLA(I):=V_ENAME;
S_TABLA(I):=V_SAL;
FETCH C1 INTO V_ENAME, V_SAL;
END LOOP;
CLOSE C1;
FOR I IN 1..V_NUM LOOP
DBMS_OUTPUT.PUT_LINE (E_TABLA(I));
DBMS_OUTPUT.PUT_LINE (S_TABLA(I));
END LOOP;
END;
/

Concepto de tabla de registros

Puesto que slo se necesita una definicin de tabla para almacenar informacin
acerca de todos los campos de una tabla de la base de datos, la tabla de registros aumenta
en gran medida la funcionalidad de las tablas PL/SQL.

Para crear una tabla de registros hay que seguir las siguientes pautas:

Definir una variable TABLA con el atributo %ROWTYPE.


Declarar una variable tabla PL/SQL que contenga informacin de los
departamentos.
Sintaxis

TYPE nb_tipo_tabla IS TABLE OF nb_tabla%ROWTYPE


INDEX BY BINARY_INTEGER;

Nb_tabla nb_tipo_tabla;

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 6 . 5


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

7. CURSORES EXPLCITOS.
7.1.- Introduccin.
7.2.- Declaracin de cursores.
7.3.- Abrir cursores.
7.4.- Recogida de datos de cursores.
7.5.- Cerrar un cursor.
7.6.- Atributos de cursores explcitos.
7.7.- Bucles FOR de cursor

7.1.- INTRODUCCIN:

Los cursores se utilizan para trabajar con consultas que devuelven ms de una fila.
Todas las sentencias SQL ejecutadas por el servidor tienen un cursor asociado, bien
implcito declarado para sentencias DML y PL/SQL SELECT.

Existen otros tipos de cursores explcitos, que son creados por el programador y
especifican el rea de memoria que debe reservar el servidor. Estos ltimos sern motivo
de estudio de este tema.

7.2.- DECLARACIN DE CURSORES

Los cursores se deben definir en la zona de declaraciones junto a las variables,


constantes, tablas, registros y excepciones. No incluyendo INTO en la declaracin del
cursor y se puede utilizar la clusula ORDER BY para procesar filas en una secuencia.

Sintaxis:

CURSOR nb_cursor IS
sentencia SELECT;

7.3.- ABRIR CURSORES

Una vez declarado el cursor procedemos a abrirlo, para ello se usa la orden OPEN,
que presenta la siguiente sintaxis :

OPEN nb_cursor;

La apertura del cursor presenta siempre las siguientes caractersticas:

Abrir el cursor para ejecutar la consulta e identificar el juego activo.


Si la consulta no devuelve ninguna fila, no se producir ninguna excepcin.
Utilizar atributos del cursor para comprobar los resultados producidos tras una
recuperacin.

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 7. 1


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

7.4. RECUPERACIN DE DATOS DEL CURSOR

Sintaxis:

FETCH nb_cursor INTO [ variable1, variable2, ... | nb_registro] ;

La sentencia FETCH recupera las filas del juego de resultados de una en una.
Despus de cada recuperacin, el cursor avanza a la siguiente fila del juego de resultados.

Directrices:

Recuperar los valores de la fila actual e introducirlos en variables de salida.


Incluir el mismo nmero de variables.
Relacionar posicionalmente las variables y las columnas.
Comprobar si el cursor tiene filas.

7.5.- CERRAR UN CURSOR

Una vez utilizado el cursor, si no se necesita ms podemos cerrarlo para que no


ocupe memoria. Para centrarlo se utiliza la orden CLOSE.

Sintaxis:

CLOSE nb_cursor;

Ejemplo 1:

Funcionamiento y manejo de los cursores:

DECLARE
CURSOR MATRI IS
SELECT MATRICULA, BECARIO FROM ALUMNOS;
TEMPORAL MATRI%ROWTYPE;
VAR1 ALUMNOS.MATRICULA%TYPE;
VAR2 ALUMNOS.MATRICULA%TYPE;
BEGIN

OPEN MATRI;
LOOP
FETCH MATRI INTO TEMPORAL;
EXIST WHEN MATRI%NOTFOUND
IF TEMPORAL.BECARIO IS NULL THEN
VAR1 := VAR1 + MATRI.MATRICULA;
ELSE
VAR2:= VAR2 + MATRI.MATRICULA;
END IF
END LOOP;
INSERT INTO TEMP(COL1,COL2) VALUES (VAR1, VAR2);
CLOSE MATRI;
END;
/

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 7. 2


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

Ejemplo 2:

Crear un bloque PL que acepte un nmero como entrada, elija a los empleados
dependiendo del nmero con el sueldo ms alto y los inserte en la tabla OTRA.

DECLARE
CURSOR EMP_CURSOR IS
SELECT ENAME, SAL FROM EMP WHERE SAL IS NOT NULL
ORDER BY SAL;
V_ENAME EMP.ENAME%TYPE;
V_SAL EMP.SAL%TYPE;
V_NUM NUMBER(3) := &NMERO;

BEGIN

OPEN EMP_CURSOR;
FETCH EMP_CURSOR INTO V_ENAME , V_SAL;
WHILE (EMP_CURSOR%ROWCOUNT <= V_NUM ) AND
EMP_CURSOR%FOUND LOOP
INSERT INTO OTRA (ENAME, SALARY)
VALUES (V_ENAME, V_SAL);
FETCH EMP_CURSOR INTO V_ENAME, V_SAL;
END LOOP;
CLOSE EMP_CURSOR;
COMMIT;
END;
/

7.6. ATRIBUTOS DE CURSORES EXPLCITOS

Un cursor posee una serie de atributos que podemos asociarle, para conocer su
estado en un momento determinado. Son los siguientes:

Atributo Tipo Descripcin


%NOTFOUND Booleano Resulta TRUE si la recuperacin ms reciente no devuelve
una fila.
%FOUND Booleano Resulta TRUE si la recuperacin ms reciente devuelve
una fila; complemento de %NOTFOUND.
%ROWCOUNT Numrico Da el nmero total de filas devueltas hasta ese momento.
%ISOPEN Booleano Resulta TRUE si el cursor est abierto.

%NOTFOUND: se activa si el ltimo FETCH no ha recuperado ninguna fila del


cursor.

LOOP
FETCH CURSOR INTO VARIABLE;
EXIT WHEN CURSOR%NOTFOUND;
END LOOP;

%FOUND: se activa si el ltimo FETCH ha recuperado alguna fila del cursor.

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 7. 3


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

LOOP
FETCH CURSOR INTO VARIABLE
IF CURSOR%FOUND THEN
;
ELSE
EXIT;
END IF;
END LOOP;

%ROWCOUNT: devuelve el nmero de filas recuperadas hasta ese momento con la


instruccin FETCH, al iniciarse vale:

LOOP
FETCH CURSOR INTO VARIABLE
IF CURSOR%ROWCOUNT = 5
THEN EXIT;
END IF;
END LOOP;

%ISOPEN: es verdadero cuando el cursor est abierto, falso si est cerrado.

IF CURSOR%ISOPEN THEN
CLOSE CURSOR;
ELSE
OPEN CURSOR;
END IF;

7.7. BUCLES FOR DE CURSOR

Un bucle FOR de cursor:

o Procesa filas en un cursor explicito.


o Abre, recupera y cierra de forma automtica.
o No declarar la variable registro, ya que se declara implcitamente.

Sintaxis:

FOR nb_registro IN nb_cursor LOOP


rdenes;

END LOOP;

Ejemplo:

Recuperar, de uno en uno, todas las lneas de articulo pedido hasta que no queden
mas lneas, utilizando un bucle FOR de cursor.
......
FOR PED_REG IN CURSOR_LIN LOOP
V_TOTAL:=V_TOTAL+(PED_REG.PRECIO*PED_REG.CANTIDAD);
I:=I+1;
TB_PRODUCTOS(I):=PED_REG.PRODUCTO;
TB_TOTAL(I):=V_TOTAL;
END LOOP;
.....

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 7. 4


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

Ejemplos de cursores (I).

Escribir un bloque PL/SQL que visualice el apellido y la fecha de alta de todos los
empleados de la tabla EMP, ordenados ascendentemente por fecha de alta en la empresa.

Bucle LOOP

DECLARE

CURSOR C_EMP
IS
SELECT ENAME, HIREDATE
FROM EMP
ORDER BY HIREDATE;

V_ENAME EMP.ENAME%TYPE;
V_HIREDATE EMP.HIREDATE%TYPE;

BEGIN

OPEN C_EMP;
LOOP
FETCH C_EMP INTO V_ENAME, V_HIREDATE;
EXIT WHEN C_EMP%NOTFOUND;
DBMS_OUTPUT.PUT_LINE (V_ENAME||'*'||V_HIREDATE);
END LOOP;
CLOSE C_EMP;

END;
/

Bucle WHILE

DECLARE

CURSOR C_EMP
IS
SELECT ENAME, HIREDATE
FROM EMP
ORDER BY HIREDATE;

V_ENAME EMP.ENAME%TYPE;
V_HIREDATE EMP.HIREDATE%TYPE;

BEGIN

OPEN C_EMP;
FETCH C_EMP INTO V_ENAME, V_HIREDATE;
WHILE C_EMP%FOUND LOOP
DBMS_OUTPUT.PUT_LINE (V_ENAME||'*'||V_HIREDATE);
FETCH C_EMP INTO V_ENAME, V_HIREDATE;
END LOOP;
CLOSE C_EMP;
END;
/

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 7. 5


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

Bucle FOR

DECLARE

CURSOR C_EMP
IS
SELECT ENAME, HIREDATE
FROM EMP
ORDER BY HIREDATE;

BEGIN

FOR I IN C_EMP LOOP


DBMS_OUTPUT.PUT_LINE (I.ENAME||'*'||I.HIREDATE);
END LOOP;

END;
/

Ejemplos de cursores (II).

Crear un bloque PL que acepte un nmero como entrada, elija a los empleados
dependiendo del nmero con el sueldo mas alto y los inserte en una tabla llamada OTRA.

CREATE TABLE OTRA (ENAME VARCHAR2(10),SAL NUMBER(7,2));

DECLARE
CURSOR EMP_CURSOR
IS
SELECT ENAME,SAL
FROM EMP WHERE SAL IS NOT NULL
ORDER BY SAL;

V_ENAME EMP.ENAME%TYPE;
V_SAL EMP.SAL%TYPE;
V_NUM NUMBER(3):=&NUMERO;

BEGIN

OPEN EMP_CURSOR;
FETCH EMP_CURSOR INTO V_ENAME,V_SAL;
WHILE(EMP_CURSOR%ROWCOUNT<=V_NUM) AND EMP_CURSOR%FOUND LOOP
INSERT INTO OTRA (ENAME,SAL) VALUES (V_ENAME,V_SAL);
FETCH EMP_CURSOR INTO V_ENAME,V_SAL;
END LOOP;
CLOSE EMP_CURSOR;
COMMIT;

END;
/

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 7. 6


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

8. CONCEPTOS AVANZADOS DE CURSORES

8.1.- Cursores con parmetros.


8.2.- Clusulas utilizadas con cursores.

8.1.- CURSORES CON PARMETROS:

Los parmetros permiten que los valores se transfieran a un cursor cuando ste
est abierto, y se puede abrir varias veces en un bloque, devolviendo un juego activo
distinto cada vez.

Cada parmetro formal de la declaracin del cursor debe tener un parmetro real
correspondiente en la sentencia OPEN. Los distintos tipos de datos del parmetro son los
mismos que los de las variables escalares, pero no se les asigna tamaos. Los nombres de los
parmetros son referenciados en la expresin de la consulta del cursor.

Sintaxis :

CURSOR nb_cursor
[ (nb_parmetro tipo_dato [ { := | DEFAULT } expr ]....)]
[RETURN tipo_return] IS
Sentencia SELECT;

De los cursores con parmetros podemos decir a modo de resumen que:

Transfieren los valores de los parmetros a un cursor cuando se abre y


se ejecuta la consulta.

Abre un cursor explcito varias veces con un juego activo distinto cada
vez.
Ejemplo:

DECLARE
CURSOR EJEMPLO (VAR1 NUMBER) IS
SELECT * FROM ALUMNOS WHERE MATRICULA > VAR1;
BEGIN
OPEN EJEMPLO (150000);

END;

8.2.- CLUSULAS UTILIZADAS EN LOS CURSORES:

FOR UPDATE

Esta clusula se coloca en la SELECT del cursor en la zona declarativa.

Permite:

Bloquear algunas filas antes de la actualizacin o supresin.

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 8. 1


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

El bloqueo explicito le permite denegar el acceso mientras dura una


transaccin.

Sintaxis:

SELECT .....
FROM .....
FOR UPDATE [ OF col_tabla_referenciada][NOWAIT];

Donde:

NOWAIT: devuelve error si las filas fueron bloqueadas en otra sesin.

Ejemplo:

Recuperar los pedidos de importes superiores a 1000$ que se han procesado hoy.

DECLARE
CURSOR C1 IS
SELECT CUSTID, ORDID
FROM ORD
WHERE ORDERDATE = SYSDATE AND TOTAL>1000.00
ORDER BY CUSTID
FOR UPDATE NOWAIT;

WHERE CURRENT OF:

Esta clusula se utiliza siempre que se haga referencia a la fila actual de un cursor
explcito, esto permitir realizar actualizaciones y supresiones a la fila que se est
tratando actualmente.

Se incluir la clusula FOR UPDATE en la consulta del cursor para bloquear primero
las filas.

Se utilizar la clusula WHERE CURRENT OF para hacer referencia en la fila actual de un


cursor explcito. Esta clusula normalmente se utiliza en la zona BEGIN .

Sintaxis:

WHERE CURRENT OF nb_cursor;

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 8. 2


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

Ejemplo:

DECLARE

CURSOR EMP_CURSOR IS
SELECT
FOR UPDATE;

BEGIN

FOR EMP_RECORD IN EMP_CURSOR LOOP
UPDATE
WHERE CURRENT OF EMP_CURSOR;

END LOOP;
COMMIT;
END;

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 8. 3


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

9. GESTIN DE EXCEPCIONES.

9.1.- Introduccin.
9.2.- Excepciones internas de PL/SQL.
9.3.- Excepciones definidas por el usuario.
9.4.- Excepciones asociadas a errores Oracle.
9.5.- Funciones para interrumpir excepciones.
9.6.- Propagacin de excepciones.
9.7.- RAISE_APPLICATION_ERROR

9.1.- INTRODUCCIN

Con las excepciones podemos tratar errores en los mensajes de Oracle. Una
excepcin es un identificador de PL/SQL que surge durante la ejecucin de un bloque y
termina con su cuerpo principal de acciones. Un bloque termina cuando PL provoca una
excepcin.

Existen dos mtodos para provocar una excepcin:

1. Si se produce un error de Oracle y surge automticamente la excepcin


asociada. Por ejemplo, el error ORA-01403 indica que no se ha recuperado
ninguna fila y es en este caso cuando PL provoca la excepcin
NO_DATA_FOUND.

2. Provoca explcitamente una excepcin, es decir, que el usuario sea el que la


predefina.

Si el bloque no tiene rea de excepciones este se interrumpe dando el servidor los


mensajes pertinentes que tenga. Si tiene rea de excepciones el error se propaga a dicha
rea, enviando el servidor el mensaje que considere oportuno.

Las excepciones pueden ser:

Implcitas: que son predefinidas y no predefinidas por el servidos Oracle


Explicitas: que son las definidas por el usuario.

Sintaxis:

EXCEPTION
WHEN excep1 [ OR excep2 ... ] THEN
ordenes;

[WHEN excep3 [ OR excep4 ] THEN
ordenes;
]
[WHEN OTHERS THEN
ordenes;
]

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 9. 1


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

Donde:

EXCEP: es el nombre de la excepcin estndar o definida por el usuario.

OTHERS: es la que irrumpe en cualquier otro caso.

9.2.- EXCEPCIONES INTERNAS DE PL/SQL (PREDEFINIDAS POR


EL SERVIDOR)

Este tipo de excepciones se disparan ante un determinado error detectado por


PL/SQL. No hay que declararlas. Disponemos de las siguientes:

Excepciones Descripcin
NO_DATA_FOUND Se produce cuando una orden del tipo SELECT
INTO no ha devuelto ningn valor.
ZERO_DIVIDE Sucede cuando se produce cuando se divide un
valor por 0.
INVALID_CURSOR Se produce cuando se produce una operacin
ilegal en un cursor.
TOO_MANY_ROWS Se produce cuando una orden SELECT INTO
devuelva ms de una fila.
INVALID_NUMBER Sucede cuando hay un fallo de conversin de una
cadena a un nmero.
DUP_VAL_ON_INDEX Se produce cuando se intenta introducir un
duplicado en una tabla.
LOGIN_DENIED Sucede cuando se introduce un nombre de
usuario o contrasea no valido.
CURSOR_ALREADY_OPEN Se produce cuando se intenta abrir un cursor que
ya est abierto.
STORAGE_ERROR Se produce cuando hay un fallo en memoria.
VALUE_ERROR Se produce cuando hay un error de operacin
aritmtica de conversin, de truncamiento o de
restriccin.
TIMEOUT_ON_RESOURCE Sucede cuando se acaba el tiempo al coger
determinados recursos.
ACCESS_INTO_NULL Se produce cuando se intenta acceder a los
atributos de un objeto no inicializado.
COLLECTION_IS_NULL Se produce cuando se intenta acceder a
elementos de una coleccin no inicializada.
NOT_LOGGED_ON Se produce cuando se intenta acceder a la base
de datos sin estar conectado a Oracle.
PROGRAM_ERROR Sucede si hay un problema interno en la ejecucin
de un programa.
ROWTYPE_MISMATCH Se produce cuando la variable HOST y la variable
PL/SQL pertenecen a tipos incompatibles.
SUBSCRIPT_OUTSIDE_LIMIT Sucede cuando se intenta acceder a una tabla o a
un array con un valor de ndice ilegal.

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 9. 2


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

Ejemplo:

Hacer un bloque PL, utilizando excepciones internas, que introduciendo dos


nmeros por teclado divida N1 entre N2.

DECLARE
NUM1 NUMBER:=&n1;
NUM2 NUMBER:=&n2;
DIVIDE NUMBER;
BEGIN
DIVIDE:= NUM1/NUM2;
EXCEPTION
WHEN ZERO_DIVIDE THEN
DBMS_OUTPUT.PUT_LINE('IMPOSIBLE DIVIDIR POR 0');
END;
/

9.3.- EXCEPCIONES DEFINIDAS POR EL USUARIO.

Para poder utilizar o crear una excepcin definida a nivel a usuario, lo primero que
se debe hacer es declararla en la zona de declaraciones. Siendo su sintaxis en la zona de
excepciones idntica a las anteriores.

Para arrancar una excepcin de usuario y pasarle el control a la seccin de


excepciones utilizaremos la orden RAISE seguida del nombre de la excepcin.

Para su utilizacin hay que dar tres pasos:

1. Se deben declarar en la seccin DECLARE de la siguiente forma:

nb_excepcin EXCEPTION;

2. Se disparan o levantan en la seccin ejecutable del programa con


la orden RAISE.

RAISE nb_excepcin;

3. Se tratan en la seccin EXCEPTION segn el formato ya


conocido.

WHEN nb_excepcin THEN tratamiento;

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 9. 3


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

Ejemplo:

Definir un cursor que seleccione ENAME y COMM, ordenado por comisin de la


tabla EMP. Transferir a la tabla otra solo aquellos cuya comisin sea no nula.

DECLARE
CURSOR C1 IS
SELECT ENAME, COMM
FROM EMP
ORDER BY 2;
V_ENAME EMP.ENAME%TYPE;
V_COM EMP.COMM%TYPE;
I BINARY_INTEGER:= 14;
CONT NUMBER:=0;
ERROR_COMMIS EXCEPTION;
BEGIN
OPEN C1;
FETCH C1 INTO V_ENAME, V_COM;
WHILE (C1%ROWCOUNT <= I) AND (C1%FOUND) LOOP
IF V_COM IS NULL THEN
RAISE ERROR_COMMIS;
END IF;
CONT:= CONT+1;
INSERT INTO OTRA3 VALUES (V_ENAME, V_COM);
FETCH C1 INTO V_ENAME, V_COM;
END LOOP;
CLOSE C1;
EXCEPTION
WHEN ERROR_COMMIS THEN
DBMS_OUTPUT.PUT_LINE (CONT ||' REGISTROS INTODUCIDOS');
END;
/

9.4.- EXCEPCIONES ASOCIADAS A ERRORES DE ORACLE. (NO


PREDEFINIDOS POR EL SERVIDOR)

Son tambin definidas por el usuario, ya que l es quien decide su asignacin y


funcionamiento, sin embargo lo que hace es definir una determinada excepcin que
responda a un tipo de error de Oracle. Para asociar una excepcin a alguno de estos
errores internos de Oracle que no tienen excepciones predefinidas asociadas.
Procederemos de la siguiente forma:

1. Definimos la excepcin en la seccin declarativa.

Nb_excepcin EXCEPTION;

2. Asociamos esa excepcin a un determinado cdigo de error mediante la directiva


del compilador PRAGMA EXCEPTION_INIT, segn el siguiente formato:

PRAGMA EXCEPTION_INIT (nb_excepcin, - nmero_error_oracle);

3. Indicamos el tratamiento de la excepcin como si se tratase de cualquier otra


excepcin definida o predefinida.

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 9. 4


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

Ejemplo:

DECLARE

ERROR_EXTERNO EXCEPTION;
PRAGMA EXCEPTION_INIT (ERROR_EXTERNO, -1547);

BEGIN
...

EXCEPTION

WHEN ERROR_EXTERNO THEN


DBMS_OUTPUT.PUT_LINE(ERROR, TABLESPACE SIN ESPACIO);

END;
/

9.5.- FUNCIONES PARA INTRODUCIR EXCEPCIONES

Cuando se produce una excepcin se pretende identificar el cdigo de error asociado o


el mensaje mediante dos funciones:

Funciones Descripcin
SQLCODE Devuelve el nmero de error de Oracle de las excepciones
internas. Se le asigna una variable NUMBER. Los valores
DECODE son los siguientes:
Valor Descripcin
0 No se encontr ninguna excepcin.
1 Excepcin definida por el usuario.
+100 Excepcin NO_DATA_FOUND.
N negativo Otro nmero de error del servidor.

SQLERRM Devuelve datos carcter que contienen el mensaje de error


asociado.

Ejemplo 1:

DECLARE
...
V_ERROR_CODE NUMBER;
V_ERROR_MENSAJE VARCHAR2(25);

BEGIN
...
EXCEPTION
WHEN OTHERS THEN

ROLLBACK;
V_ERROR_CODE:= SQLCODE;
V_ERROR_MENSAJE:= SQLERROR;
...
END;

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 9. 5


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

Ejemplo 2:

Ejemplo recopilatorio de todo lo visto en la unidad.

DECLARE
COD_ERR NUMBER(6);
VNIF VARCHAR2(10);
VNOM VARCHAR2(15);
ERR_BLANCOS EXCEPTION;
NO_HAY_ESPACIO EXCEPTION;
PRAGMA EXCEPTION_INIT(NO_HAY_ESPACIO, -1547);
BEGIN
SELECT COL1, COL2 INTO VNIF, VNOM
FROM TEMP2;
IF SUBSTR(VNOM,1,1)<= THEN
RAISE ERR_BLANCOS;
END IF;
UPDATE CLIENTES SET NOMBRE=VNOM WHERE NIF=VNIF;
EXCEPTION
WHEN ERR_BLANCOS THEN
INSERT INTO TEMP2(COL1) VALUES (ERR BLANCOS);
WHEN NO_HAY_ESPACIO THEN
INSERT INTO TEMP2(COL1) VALUES (ERR TABLESPACE);
WHEN NO_DATA_FOUND THEN
INSERT INTO TEMP2(COL1) VALUES (ERR NO HABIA DATOS);
WHEN TOO_MANY_ROWS THEN
INSERT INTO TEMP2(COL1) VALUES (ERR DEMASIADOS DATOS);
WHEN OTHERS THEN
COD_ERR := SQLCODE;
INSERT INTO TEMP2(COL1) VALUES (COD_ERR);
END;
/

9.6.- PROPAGACIN DE EXCEPCIONES

Cuando un subprograma gestiona una excepcin y este termina normalmente el


control se reanuda en el bloque padre despus del END del subbloque.

Sin embargo, si hubiese una excepcin en el hijo sta se propaga al padre, hasta que
encuentre un manejador de la misma.

Las excepciones tratadas en el subbloque han de ser declaradas en el bloque


principal.

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 9. 6


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

DECLARE
...X
...Y
...
BEGIN
...
...
BEGIN
...
EXCEPTION
...X
...Y
END;

...
EXCEPTION
...
...
END;
/

9.7.- RAISE_APPLICATION_ERROR

El paquete DBMS_STANDARD incluye un procedimiento muy til llamado


RAISE_APPLICATIOM_ERROR que sirve para levantar errores, definir y enviar mensajes
de error.

Sintaxis:

RAISE_APPLICATION_ERROR(-n_error, mensaje_error);

Donde nmero_error: es un nmero comprendido entre 20000 y 20999 y


mensaje_error es una cadena de hasta 512 bytes.

Ejemplo:

PROCEDURE SUBIR_SUELDO
(NUM_EMPLE NUMBER, INCREMENTO NUMBER)
IS
SALARIO ACTUAL_NUMBER;
BEGIN
SELECT SALARIO INTO SALARIO_ACTUAL
FROM EMPLEADOS
WHERE EMP_NO = NUM_EMPLE;
IF SALARIO_ACTUAL IS NULL THEN
RAISE_APPLICATION_ERROR(-20010, SALARIO NULO);
ELSE
UPDATE EMPLEADOS
SET SUELDO =SALARIO_ACTUAL+ INCREMENTO
WHERE EMP_NO = NUM_EMPLE;
END IF ;
END SUBIR_SUELDO;

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 9. 7


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

10.- PROCEDIMIENTOS

10.1.- Introduccin.
10.2.- Modos de parmetros.
10.3.- Mtodos para pasar parmetros.
10.4.- Ms sobre procedimientos.

10.1.- INTRODUCCIN

Un procedimiento es un bloque PL nombrado que realiza una determinada accin.


Est almacenado en la Base de Datos como un objeto de la misma y puede ser ejecutado
mltiples veces.

Los procedimientos promueven la reutilizacin y el mantenimiento de los programas,


y una vez validados, pueden utilizarse en muchas aplicaciones. Si la definicin cambia, solo
se ve afectado el procedimiento y esto simplifica en gran mediada el mantenimiento.

Sintaxis:

CREATE [OR REPLACE] PROCEDURE nb_procedimiento


(argumento1 [ modo 1] tipo_de_dato1,
argumento2 [ modo2] tipo_de_dato2,
...)
IS | AS
Bloque PL/SQL;

Donde:

ARGUMENTO: nombre de la variable PL cuyo valor se recibe


MODO: IN, OUT, IN OUT.
TIPO_DE_DATO: tipo de dato del argumento.

Creacin de un procedimiento en SQL * PLUS

1. Introducir CREATE PROCEDURE en un editor y salvarlo en un SCRIPT.


2. Desde SQL*PLUS, ejecutar el SCRIPT, para compilar el cdigo fuente y
almacenarlo en la Base de Datos.
3. Llamar al procedimiento y ejecutarlo si no tiene errores.

Los procedimientos no llevan la palabra DECLARE. Si los procedimientos se crean


dentro de bloques PL no se introducir la clusula CREATE PROCEDURE se pone
nicamente PROCEDURE nb_procedimiento

10.2.- MODOS DE PARMETROS.

Podemos transferir valores desde el entorno de llamada a travs de parmetros.


Existen 3 modos de parmetros:

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 10. 1


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

IN OUT IN OUT
Por defecto. Tiene que especificarse. Tiene que especificarse.
Valor que se pasa al Devuelve al entorno de Valor que se pasa al
subprograma. llamada. subprograma. Devuelve al
entorno de llamada.
Parmetro formal constante. Variable no inicializada. Variable inicializada.
Parmetro actual puede ser Tiene que ser una variable. Tiene que ser una variable.
un literal, expresin,
constante o variable
inicializada.

IN

Pasa un valor constante desde el entorno de llamada al procedimiento. Valor por


defecto, es el valor que se pasa a un subprograma, pudiendo ser literal, expresin,
constante o variable.

Ejemplo:

Crear un procedimiento que incremente el salario de un empleado un 10%, se


introducir el cdigo del empleado como parmetro de entrada.

CREATE OR REPLACE PROCEDURE PROC1


(V_ID IN EMP.EMPNO%TYPE)
IS
BEGIN
UPDATE EMP SET SAL= SAL*1.10 WHERE EMPNO = V_ID;
END PROC1;
/

SQL> EXECUTE PROC1(7934);

OUT

Pasa un valor desde el procedimiento al entorno de llamada. Tiene que ser una
variable.

Ejemplo:

Crear un procedimiento QUERY_EMP con tres parmetros: uno de entrada, que


permita introducir el cdigo del empleado y dos de salida que permita visualizar el salario y
el oficio.

CREATE OR REPLACE PROCEDURE QUERY_EMP


(V_ID IN EMP.EMPNO%TYPE,
V_SAL OUT EMP.SAL%TYPE,
V_JOB OUT EMP.JOB%TYPE)
IS
BEGIN
SELECT SAL, JOB INTO V_SAL,V_JOB FROM EMP
WHERE EMPNO = V_ID;
END QUERY_EMP;
/

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 10 . 2


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

El procedimiento est creado, ahora hay crear unas variables host y ejecutarlo,
puesto que no hay programa principal que llame al procedimiento.

SQL> VARIABLE G_SAL NUMBER;


SQL> VARIABLE G_JOB VARCHAR2(15)
SQL> EXECUTE QUERY_EMP (7839,:G_SAL,:G_JOB)
SQL> PRINT G_SAL
SQL> PRINT G_JOB

IN OUT

Valor que se pasa al procedimiento y vuelve al entorno de llamada. Tiene que ser una
variable inicializada.

Ejemplo:

Crear un procedimiento llamado CAMBIO, que introduciendo una cadena la devuelva


entre parntesis.

CREATE OR REPLACE PROCEDURE CAMBIO


(V_CAM IN OUT VARCHAR2)
IS
BEGIN
V_CAM := ( || V_CAM || ) ;
END CAMBIO;
/

SQL> VARIABLE G_CAM VARCHAR2(25);


BEGIN
:G_CAM := HOLA;
END;
/

SQL> EXECUTE CAMBIO (:G_CAM);


PRINT G_CAM;

10.3.- MTODOS PARA PASAR PARMETROS

Existen tres mtodos para pasar parmetros:

1. Posicional: Lista de valores en el orden que se declaran los parmetros


2. Asociacin nombrada: Lista de valores en orden arbitrario mediante la asignacin
(=>).
3. Mixto: Mezcla de los dos anteriores. Lista de los primeros valores posicionalmente,
y el resto, utilizando la sintaxis especial del mtodo nombrado.

Para llamar desde un programa principal a un procedimiento se escribe:


NB_PROCEDIMIENTO (PARMETROS).

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 10. 3


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

Ejemplo:

Crear un procedimiento llamado AADIR que permita introducir elementos en la


tabla DEPT, teniendo en cuenta que el cdigo de departamento es obligatorio y que si no
se asigna valor al resto de los campos tendrn un valor por defecto. Crear posteriormente
un bloque PL annimo que invoque al procedimiento y aada registros por los mtodos
anteriormente explicados.

CREATE OR REPLACE PROCEDURE AADIR


(V_DEPTNO IN NUMBER,
V_DNAME IN DEPT.DNAME%TYPE DEFAULT XXXXX,
V_LOC IN DEPT.LOC%TYPE DEFAULT CCCCC)
IS
BEGIN
INSERT INTO DEPT VALUES (V_DEPTNO, V_DNAME, V_LOC);
END AADIR;
/

Programa principal:

BEGIN
AADIR(60);
AADIR(70,DATOS,MADRID);
AADIR (V_LOC=> BARCELONA,V_DEPTNO=> 75);
END;
/

10.4.- MAS SOBRE PROCEDIMIENTOS

SQL * PLUS
Ejecucin de forma aislada de un EXECUTE nb_procedimiento (parmetros);
procedimiento.
Ejecucin de procedimiento desde Nb_procedimiento (parmetros);
un programa principal.
Borrado de un procedimiento. DROP PROCEDURE nb_procedimiento;

PROCEDURE BUILDER
Ejecucin de forma aislada de un Nb_procedimiento (parmetros);
procedimiento.
Ejecucin de procedimiento desde Nb_procedimiento (parmetros);
un programa principal.
Borrado de un procedimiento. DROP PROCEDURE nb_procedimiento;

Los procedimientos los encontramos en la tabla USER_OBJECTS del Diccionario


de Datos.

SELECT OBJECT_NAME, OBJECT_TYPE, STATUS


FROM USER_OBJECTS
WHERE OBJECT_TYPE = PROCEDURE;

La tabla USER_SOURCE del Diccionario de Datos, permite ver el cdigo fuente de


los procedimientos, mediante la siguiente sentencia:

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 10 . 4


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

SELECT LINE, SUBSTR (TEXT,1,60)


FROM USER_SOURCE
WHERE NAME = NB_PROCEDURE;

Para volver a compilar un procedimiento utilizamos la orden ALTER

ALTER { PROCEDURE|FUNCTION} nb_subprograma COMPILE;

Esto vale tanto para procedimientos como para funciones.

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 10. 5


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

11.- CREACIN DE FUNCIONES

11.1.- Introduccin.
11.2.- Ejecucin de funciones.
11.3.- Ms sobre funciones.
11.4.- Procedimientos y funciones.
11.5.- Recursividad.

11.1.- INTRODUCCIN

Una funcin es un bloque nombrado PL/SQL que devuelve un valor, solamente tiene
parmetros de entrada. Est almacenada en la Base de Datos como un objeto de la misma
para repetidas ejecuciones.

Sintaxis:

CREATE [ OR REPLACE] FUNCTION nb_funcin


(argumento1 [modo1] tipo_dato1,
argumento2 [modo2] tipo_dato2,
...)
RETURN tipo_de_dato
IS | AS
Bloque PL/SQL;
/

Donde:

ARGUMENTO: Nombre de la variable PL cuyo valor se pasa en la funcin.


TIPO_DATO: tipo de dato del parmetro.
RETURN TIPO_DE_DATO: Indica el tipo de dato que la funcin debe devolver.
MODO: siempre es IN y se puede omitir.

Creacin de una funcin

Para crear una funcin es conveniente seguir los siguientes pasos:

1. Introducir el texto en el editor y guardarlo en un SCRIPT. SQL.

2. Desde SQL*Plus ejecutar el SCRIPT para compilar el cdigo y que ste


quede almacenado en la base de datos.

3. Llamar a la funcin cuando necesite ser ejecutada.

Si se crea una funcin dentro de un bloque PL no se escribir la clusula CREATE,


nicamente FUNCTION nb_funcin.

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg.: 11. 1


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

Ejemplo:

Crear una funcin que devuelva el salario de un empleado cuyo cdigo es introducido
como parmetro. La funcin se llamar GET_SAL;

CREATE OR REPLACE FUNCTION GET_SAL


(V_ID EMP.EMPNO%TYPE)
RETURN NUMBER
IS
V_SALARY EMP.SAL%TYPE := 0;
BEGIN
SELECT SAL INTO V_SALARY FROM EMP WHERE EMPNO= V_ID;
RETURN V_SALARY;
END GET_SAL;
/

11.2.- EJECUCIN DE FUNCIONES

A.- Mediante una variable HOST:

1. Definir una variable host: VARIABLE nb_variable tipo_dato;


2. Ejecutar de la siguiente forma:
EXECUTE :nb_variable := nb_funcin (valor_de_entrada);
3. Imprimir la variable host: PRINT nb_variable.

B.- Invocarla desde un bloque PL, cargndola en una variable.


<VARIABLE> := nb_funcion (parmetro)

Ejemplo 1:

Disear una funcin que devuelva el nmero de aos comprendidos entre dos
fechas, las cuales son introducidas como parmetros.

CREATE OR REPLACE FUNCTION FUNC_FECHA (FECHA1 DATE, FECHA2 DATE)


RETURN NUMBER
AS
V_AOS NUMBER(6);
BEGIN
V_AOS := ABS(TRUNC(MONTHS_BETWEEN(FECHA2,FECHA1)/12));
RETURN (V_AOS);
END FUNC_FECHA;
/

Ejemplo 2:

Crear un bloque annimo que llama a la funcin y devuelva su valor.

DECLARE
V_RES NUMBER;
BEGIN
V_RES:= FUNC_FECHA (03/12/95, 08/08/99);
DBMS_OUTPUT.PUT_LINE(V_RES);
END;
/

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg.: 11. 2


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

Una funcin de usuario puede ser invocada desde una orden SQL:

Como columna de una SELECT.


En las condiciones WHERE y HAVING.
En las clusulas ORDER BY y GROUP BY.
Clusula VALUES en el comando INSERT.
En la clusula SET del comando UPDATE.

11.3.- MAS SOBRE FUNCIONES

Para borrar funciones se utiliza la siguiente orden:

DROP FUNCTION nb_funcion;

Las funciones las encontramos en la tabla USER_OBJECTS del Diccionario de


Datos.

SELECT OBJECT_NAME, OBJECT_TYPE, STATUS


FROM USER_OBJECTS
WHERE OBJECT_TYPE = FUNCTION;

La tabla USER_SOURCE del Diccionario de Datos, permite ver el cdigo fuente de


las funciones, mediante la siguiente sentencia:

SELECT LINE, SUBSTR (TEXT,1,60)


FROM USER_SOURCE
WHERE NAME = NB_FUNCION;

Para volver a compilar una funcin utilizamos la orden ALTER:

ALTER {PROCEDURE|FUNCTION} nb_subprograma COMPILE;

Esto vale tanto para procedimientos como para funciones.

11.4.- PROCEDIMIENTOS Y FUNCIONES

Se crea un procedimiento para almacenar una serie de acciones para ejecuciones


posteriores, pudiendo contener cero o ms parmetros, que pueden transferirse desde el
entorno de llamada, no teniendo que devolver un valor.

Se crea una funcin cuando se quiere calcular un valor, el cual, debe ser devuelto al
entorno de llamada. Una funcin puede contener varios parmetros de entrada pero una
sola salida al programa principal.

Los beneficios de los procedimientos y las funciones son:

1. Mejorar el rendimiento.
2. Mejorar el mantenimiento.
3. Mejorar la seguridad e integridad de los datos.

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg.: 11. 3


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

11.5.- RECURSIVIDAD

PL permite la posibilidad de escribir programas recursivos incluyendo RETURN y el


nombre de la funcin o el procedimiento segn se requiera.

Ejemplo:

Disear una funcin recursiva que calcule el factorial de un nmero. La llamada se


har desde un bloque annimo.

CREATE OR REPLACE FUNCTION F_RECURSIVA


(N NUMBER)

RETURN NUMBER

IS
BEGIN
IF
N=0 THEN RETURN 1;
ELSE
RETURN N*F_RECURSIVA(N-1);
END IF;
END F_RECURSIVA;
/

Ejecucin de la funcin anterior a travs de un bloque PL annimo:

DECLARE
V_SOL NUMBER;
BEGIN
V_SOL := F_RECURSIVA (&NUM);
DBMS_OUTPUT.PUT_LINE (V_SOL);
END;
/

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg.: 11. 4


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

12. CREACIN DE PAQUETES (I).

12.1.- Introduccin.
12.2.- Sintaxis de creacin de paquetes.
12.3.- Utilizacin de los objetos definidos en el paquete.
12.4.- Borrado de un paquete.
12.5.- Declaraciones de cursores en un paquete.
12.6.- Ejemplo de creacin de paquetes.

12.1.- INTRODUCCIN.

Los paquetes se utilizan para guardar subprogramas y otros objetos de la base de


datos. No pueden ser llamados, parametrizados o anidados. Permiten a Oracle8 leer
mltiples objetos en memoria una sola

Estn compuestos por dos partes:

Cabecera o especificacin:

En esta se declaran variables, excepciones, constantes, cursores y


subprogramas disponibles para el usuario.

Cuerpo:

Donde se definen completamente los cursores y los subprogramas.

Los paquetes presentan las siguientes ventajas:

1. Modularidad: de manera lgica encapsulamos en un mdulo nombrado las


estructuras de programa relacionadas.
2. Diseo ms sencillo de la aplicacin: podemos codificar y compilar una
especificacin sin su cuerpo, despus tambin se podr compilar los
subprogramas almacenados que referencian al paquete.
3. Informacin oculta: podemos decidir que paquetes son pblicos o privados.
4. Funcionalidad aadida: las variables y cursores pblicos pueden ser
compartidos por todos los subprogramas que se ejecutan en el entorno.
5. Mejor rendimiento: cuando llamamos a un paquete por primera vez, se carga
en memoria el paquete completo y en llamadas posteriores a los
subprogramas relacionados con el paquete ya no necesitan hacer I/O en el
disco.
6. Sobrecarga: podemos crear subprogramas mltiples con el mismo nombre en
el mismo paquete.

Desarrollo de un paquete:

Salvar el texto en un SCRIPT de extensin .SQL


La cabecera puede existir sin cuerpo pero el cuerpo no puede existir sin
cabecera

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 12. 1


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

Si se incorpora al paquete un procedimiento antes almacenado, este se


debe borrar.

12.2.- SINTAXIS DE LA CREACIN DE PAQUETES.

CABECERA O ESPECIFICACIN

CREATE [OR REPLACE] PACKAGE nb_paquete


IS | AS
< Declaraciones de tipos, constante, variable, cursores, excepciones y otros
objetos pblicos>
< Especificacin de los subprogramas>
END nb_paquete;
/

CUERPO

CREATE [ OR REPLACE] PACKAGE BODY nb_paquete


IS | AS
< Declaraciones de tipo, constantes, variables, cursores, excepciones y
otros objetos privados>
< Cuerpo de los subprogramas>
< Instrucciones iniciales>
END nb_paquete;
/

12.3.- UTILIZACIN DE LOS OBJETOS DEFINIDOS EN EL


PAQUETE

Generalmente los objetos definidos en el paquete pueden ser utilizados por otros
paquetes, siempre y cuando sean pblicos (estn definidos en la cabecera). Aquellos
definidos en el cuerpo son para uso exclusivo del paquete y se les llama privados.

Los paquetes se ejecutan con la instruccin EXECUTE.

Sintaxis:

EXECUTE nb_paquete . nb_subprograma (parmetros);

12.4.- BORRADO DE UN PAQUETE.

Hay que borrar por un lado la cabecera y por otro el cuerpo, utilizando para ello la
siguiente sintaxis:

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 12 . 2


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

DROP PACKAGE nb_paquete;

DROP PACKAGE BODY nb_paquete;

Estos objetos se encuentran en el mismo lugar del Diccionario de Datos que los
procedimientos y las funciones es decir en las tablas USER_OBJECTS y USER_SOURCE.

12.5.- DECLARACIN DE CURSORES EN UN PAQUETE

Para declarar los cursores y que estos sean accesibles en el paquete hay que
hacerlo en la cabecera y desarrollarlos en el cuerpo.

La declaracin del cursor se incluir en la cabecera del paquete indicando el nombre


del cursor, los parmetros si procede y el tipo devuelto. Este ltimo se indicar mediante
RETURN tipo_de_dato; para cursores que devuelven filas enteras normalmente se usar
%ROWTYPE .

CREATE PACKAGE EMPL_ECC


AS
...
CURSOR C1 RETURN EMPLE%ROWTYPE;
...
END EMPLE_ECC;

CREATE PAKAGE BODY EMPL_ECC


AS
...
CURSOR C1 RETURN EMPLE%ROWTYPE
SELECT *
FROM EMPLE
WHERE SALARIO >100000;
.....
END EMPL_ECC;

12.6.- EJEMPLO DE CREACIN DE PAQUETES.

En primer lugar se crear la cabecera o especificacin del paquete segn el formato


indicado.

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 12. 3


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

CREATE OR REPLACE PACKAGE BUSCAR_EMP


AS
TYPE T_REG_EMP IS RECORD
( NUM_EMPLEADO EMP.EMPNO%TYPE,
APELLIDO EMP.ENAME%TYPE,
OFICIO EMP.JOB%TYPE,
SALARIO EMP.SAL%TYPE,
DEPARTAMENTO EMP.DEPTNO%TYPE);

PROCEDURE VER_POR_NUMERO
( V_EMPNO EMP.EMPNO%TYPE);

PROCEDURE VER_POR_APELLIDO
( V_APELLIDO EMP.ENAME%TYPE);

FUNCTION DATOS
( V_EMPNO EMP.EMPNO%TYPE)
RETURN T_REG_EMP;

END BUSCAR_EMP;
/

En segundo lugar se crear el cuerpo del paquete y la declaracin de objetos


globales.

CREATE OR REPLACE PACKAGE BODY BUSCAR_EMP


IS
VG_EMP T_REG_EMP;
PROCEDURE VER_EMPLE;

PROCEDURE VER_POR_NUMERO
( V_EMPNO EMP.EMPNO%TYPE)
IS
BEGIN
SELECT EMPNO, ENAME, JOB, SAL, DEPTNO INTO VG_EMP
FROM EMP WHERE EMPNO=V_EMPNO;
VER_EMPLE;
END VER_POR_NUMERO;

PROCEDURE VER_POR_APELLIDO
(V_APELLIDO EMP.ENAME%TYPE)
IS
BEGIN
SELECT EMPNO, ENAME, JOB, SAL, DEPTNO INTO VG_EMP
FROM EMP WHERE ENAME=V_APELLIDO;
VER_EMPLE;
END VER_POR_APELLIDO;

FUNCTION DATOS
(V_EMPNO EMP.EMPNO%TYPE)
RETURN T_REG_EMP
IS
BEGIN
SELECT EMPNO, ENAME, JOB, SAL, DEPTNO INTO VG_EMP
FROM EMP WHERE EMPNO=V_EMPNO;
RETURN VG_EMP;
END DATOS;

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 12 . 4


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

PROCEDURE VER_EMPLE
IS
BEGIN
DBMS_OUTPUT.PUT_LINE (VG_EMP.NUM_EMPLEADO || '*' ||
VG_EMP.APELLIDO || '*' || VG_EMP.OFICIO || '*' ||
VG_EMP.SALARIO || '*' || VG_EMP.DEPARTAMENTO);
END VER_EMPLE;

END BUSCAR_EMP;
/

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 12. 5


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

13. CREACIN DE PAQUETES (II).

13.1.- Sobrecarga.
13.2.- Restricciones de funciones de paquetes usadas en sql.
13.3.- Paquetes proporcionados por ORACLE.
13.4.- El paquete DBMS_OUTPUT.
13.5.- El paquete DBMS_DDL.

13.1.- SOBRECARGA.

La sobrecarga:

Permite utilizar el mismo nombre para diferentes subprogramas dentro de un


paquete.

Los parmetros formales de los subprogramas tiene que diferenciarse en


nmero, orden o tipo de datos.

Los programas sobrecargados deben ser subprogramas locales o empaquetados.

Ejemplo:

Inicializar los 50 primeros registros en dos tablas PL/SQL.

PROCEDURE INITIALIZE (TAB OUT DATATABTYP, N INTEGER) IS


BEGIN
FOR I IN I..N LOOP
TAB(I) := SYSDATE;
END LOOP;
END INITIALIZE;

PROCEDURE INITIALIZE (TAB OUT REALTABTYP, N INTEGER) IS


BEGIN
FOR I IN 1..N LOOP
TAB(I) := 1000;
END LOOP;
END INITIALIZE;

DECLARE
TYPE DATATABTYP IS TABLE OF DATE
INDEX BY BYNARY_INTEGER;
TYPE REALTAB IS TABLE OF REAL
INDEX BY BYNARY INTEGER;
HIREDATE_TAB DATATABTYP;
SAL_TAB REALTABTYP;
INDX BYNARY_INTEGER;

BEGIN
INDX := 50;
INITIALIZE (HIREDATE_TAB, INDX); --LLAMAR A LA 1 VERSIN
INITIALIZE (SAL_TAB, INDX); --LLAMAR A LA 2 VERSIN
...
END;

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 13. 1


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

13.2.- RESTRICCIONES DE FUNCIONES DE PAQUETES USADAS EN


SQL.

Las restricciones sobre las funciones de un paquete utilizadas en SQL son las
siguientes:

No se permiten INSERT, UPDATE o DELETE.

Slo funciones locales pueden modificar variables de un paquete.

Las funciones remotas no pueden leer o escribir variables remotas de un


paquete.

Las funciones que leen o escriben variables de un paquete no pueden usar la


opcin de consultas en paralelo (parallel query).

Las llamadas a subprogramas que rompan las restricciones anteriores no se


permiten.

13.3.- PAQUETES PROPORCIONADOS POR ORACLE

Varios procedimientos empaquetados vienen con el propio Oracle para permitir


tanto el acceso a PL/SQL a ciertas caractersticas de SQL, como para ampliar la
funcionalidad de la BD. Estos paquetes son:

Paquete Descripcin

DBMS_ALERT Proporciona notificacin de eventos de la BD.


DBMS_APLICATION_INFO Permite a las herramientas de aplicacin y
desarrolladores de aplicaciones informar a la BD del
alto nivel de las acciones que se estn realizando
actualmente.
DBMS_DDL Recompila procedimientos, funciones y paquetes, y
analiza ndices, tablas y clusters.
DBMS_DESCRIBE Devuelve una descripcin de los argumentos para el
procedimiento almacenado.
DBMS_JOB Regula la ejecucin peridica de cdigo PL/SQL.
DBMS_LOCK Solicita, convierte y libera bloqueos, los cuales son
gestionados por los servicios de gestin de bloqueos de
la BD.
DBMS_MAIL Enva mensajes desde Oracle Server directamente a un
identificador Oracle Mail.
DBMS_OUTPUT Da salida a valores y mensajes desde disparadores,
procedimientos almacenados o funciones.
DBMS_PIPE Enva mensajes desde una sesin a otra en la misma
instancia.

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 13 . 2


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

DBMS_SESSION Proporciona acceso a SQL para enviar sentencias que


alteren la sesin y obtener informacin de la sesin.
DBMS_SHARED_POOL Mantiene objetos en la memoria compartida de manera
que no sean liberados por el mecanismo LRU habitual.
DBMS_SQL Utiliza SQL dinmico para acceder a la BD.
DBMS_TRANSACTION Controla transacciones lgicas y mejora el rendimiento
de transacciones cortas no distribuidas.
DBMS_UTILITY Analiza objetos en un esquema particular, comprueba si
el servidor se est ejecutando en modo paralelo y
devuelve el tiempo.
UTL_FILE Aade capacidades de INPUT / OUTPUT a ficheros
PL/SQL.

13.4.- EL PAQUETE DBMS_OUTPUT

Emite valores y mensajes desde disparadores, procedimientos almacenados y


funciones.

Usos prcticos:
Puede dar salida a resultados intermedios para propsitos de depuracin.
Este paquete permite a los desarrolladores seguir de cerca la ejecucin de una
funcin o un procedimiento, enviando mensajes y valores al bfer de salida.

Funcin o procedimiento Descripcin

PUT Aade texto desde el procedimiento a la lnea actual del


bfer de salida.
NEW_LINE Sita un marcador de final de lnea en el bfer de salida.
PUT_LINE Combina la accin de PUT y NEW_LINE.
GET_LINE Recupera la lnea actual del bfer de salida dentro del
procedimiento.
ENABLE/DISABLE Habilita o deshabilita las llamadas a los procedimientos
DBMS_OUTPUT .

13.5.- EL PAQUETE DBMS_DDL

Recompila procedimientos, funciones y paquetes y analiza ndices, tablas y cluster.


No est permitido en disparadores, ni en procedimientos llamados desde ORACLE*Forms o
en sesiones remotas.

Funcin o procedimiento Descripcin

ALTER_COMPILE Recompila procedimientos, funciones o paquetes.


ANALYZE_OBJECT Analiza ndices, tablas o cluster. El clculo es para todos
los registros o para un porcentaje de registros.

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 13. 3


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

14.- CREACIN DE TRIGGERS EN UNA BASE DE DATOS

14.1.- Introduccin.
14.2.- Componentes de un TRIGGER.
14.3.- Sintaxis para la creacin de un TRIGGER a nivel sentencia.
14.4.- Creacin de TRIGGER a nivel registro.
14.5.- Diferencias entre TRIGGER y procedimiento.
14.6.- Gestin y borrado de TRIGGER.
14.7.- Pruebas sobre TRIGGERS.
14.8.- Reglas que gobiernan los TRIGGERS.
14.9.- Implementacin de TRIGGERS.
14.10.- TRIGGERS sobre vistas.

14.1.- INTRODUCCIN

Un TRIGGER es un bloque PL/SQL que se ejecuta implcitamente cuando ocurre un


evento.

Los TRIGGER pueden ser de dos tipos:

1. De la base de datos: los cuales se ejecutan de forma implcita cuando se lanza una
sentencia DML contra una tabla.

2. De aplicacin: se ejecutan de forma implcita cuando ocurre un evento particular


en la aplicacin.

Gua para disear triggers:

Un TRIGGER garantiza que cuando se realiza una operacin especfica, se realicen


tambin las acciones relacionadas.

Utilizar TRIGGERS para operaciones globales.

No definir TRIGGER para implementar reglas de integridad, que puedan hacerse


mediante restricciones declarativas.

No abusar de los TRIGGERS, pues pueden dar lugar a interdependencias complejas.

14.2.- COMPONENTES DE UN TRIGGER

Para crear un TRIGGER hay que tener en cuenta:

1.- Momento en que se ejecuta el TRIGGER con relacin al evento, admitiendo


dos valores:

BEFORE: el TRIGGER se ejecuta antes del evento (sentencia


DML).
AFTER: el TRIGGER se ejecuta despus del evento.

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 14. 1


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

2.- Evento o disparador: pueden ser tres:

INSERT
DELETE
UPDATE

3.- Tipos de TRIGGERS: Los TRIGGERS pueden ser de dos tipos dependiendo
de la ejecucin del cuerpo del mismo:

De sentencia: el cuerpo del TRIGGER se ejecuta una vez para el


evento.
De fila: el cuerpo del TRIGGER se ejecuta una vez para cada
registro afectado por el evento.

4.- Cuerpo del TRIGGER: o la accin que debe realizar el TRIGGER, que es un
bloque PL annimo.

14.3.- SINTAXIS PARA LA CREACIN DE UN TRIGGER A NIVEL


SENTENCIA.

Sintaxis.

CREATE [OR REPLACE] TRIGGER nb_trigger


{BEFORE | AFTER } evento1 [ OR evento2 OR evento3 ...]
ON table_name
Bloque PL/SQL;

Donde evento es una sentencia INSERT, DELETE o UPDATE

Ejemplo:

Disear un TRIGGER llamado seguridad que restrinja la insercin de elementos los


das 31 y 1 de todos los meses. Ser a nivel sentencia y se ejecutar antes de producirse el
evento.

CREATE OR REPLACE TRIGGER SEGURIDAD


BEFORE INSERT ON EMP
BEGIN
IF(TO_CHAR(SYSDATE, 'DD') IN (30,31)) THEN
RAISE_APPLICATION_ERROR (-20500,'NO SE PUEDE INSERTAR
NI EL DIA 30 NI EL 31');
END IF;
END;
/

Este TRIGGER se ejecutar cuando intentemos realizar una instruccin INSERT en


la tabla EMP un 30 o un 31 de cualquier mes de cualquier ao.

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg.: 14. 2


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

Supongamos que hoy es 30 de enero de 2002 si intentemos insertar un elemento


sucede lo siguiente:

INSERT INTO EMP


VALUES (2000,'MARY','SALESMAN, 7902,'SYSDATE',100,200,10);

INSERT INTO EMP VALUES


*
ERROR en lnea 1:
ORA-20500: NO SE PUEDE INSERTAR NI EL DIA 30 NI EL 31
ORA-06512: en "SCOTT.SEGURIDAD", lnea 3
ORA-04088: error durante la ejecucin del disparador
'SCOTT.SEGURIDAD'

La clusula RAISE_APPLICATION_ERROR imprime el mensaje de usuario y


provoca que falle. Su sintaxis es:

RAISE_APPLICATION_ERROR (- nmero, mensaje);

Cuando un trigger falla, Oracle hace ROLLBACK sobre todas las sentencias del
TRIGGER.

Se pueden combinar varios eventos de TRIGGER en uno solo, aprovechando los


siguientes predicados condicionales:

INSERTING
DELETING
UPDATING

Ejemplo:

Modificar el ejemplo anterior, para que esto ocurra al realizar una insercin,
modificacin o eliminacin de datos los das 30 y 31 de cada mes.

CREATE OR REPLACE TRIGGER SEGURIDAD


BEFORE INSERT OR UPDATE OR DELETE
ON EMP
BEGIN
IF (TO_CHAR (SYSDATE,'DD') in (30, 31)) THEN
IF DELETING THEN
RAISE_APPLICATION_ERROR (-20501, 'NO SE PUEDE BORRAR LOS
DIAS 30 Y 31');
ELSIF INSERTING THEN
RAISE_APPLICATION_ERROR (-20502, 'NO SE PUEDE INSERTAR LOS
DIAS 30 Y 31');
ELSIF UPDATING ('SAL') THEN
RAISE_APPLICATION_ERROR (-20503, 'NO SE PUEDE MODIFICAR EL
SALARIO LOS DIAS 30 Y 31');
ELSE
RAISE_APPLICATION_ERROR (-20504, 'NO SE PUEDE
MODIFICAR LOS DIAS 30 Y 31');
END IF;
END IF;
END;
/

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 14. 3


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

Nota: La clusula updating (SAL) indica que la columna sal no puede ser modificada, si
en vez de poner elsif updating (SAL) then ponemos directamente else no podremos
realizar ninguna modificacin en ninguna columna, sino, slo nos prohibira modificar sal o
para prohibir todas las modificaciones tendramos que poner updating para todas las
columnas.

14.4.- CREACIN DE TRIGGER A NIVEL REGISTRO.

Sintaxis:

CREATE [OR REPLACE] TRIGGER nb_triger


{BEFORE|AFTER} evento 1 [OR evento2 OR evento3 ...]
ON table_name
[REFERENCES {OLD AS old | NEW AS new}]
FOR EACH ROW
[WHEN condicin]
Bloque PL/SQL;

Donde:

EVENTO: si el evento es UPDATE tiene la siguiente sintaxis: UPDATE [OF nb_col].


FOR EACH ROW: indica que el TRIGGER es a nivel registro.
WHEN condicin: evala la condicin del TRIGGER.
REFERENCES...: permite cambiar los prefijos OLD y NEW por otros.

Ejemplo:

Crear un disparador llamado auditar_subida_salario que se ejecute despus de cada


modificacin en la columna SAL en la tabla EMP. Se guardarn los valores insertados en
otra tabla llamada AUDITAREMPLE.

En primer lugar creamos la tabla:

CREATE TABLE AUDITAREMPLE


(COL1 VARCHAR2(200));

En segundo lugar cremos el TRIGGER:

CREATE OR REPLACE TRIGGER AUDITAR_SUBIDA_SALARIO


AFTER UPDATE OF SAL
ON EMP
FOR EACH ROW
BEGIN
INSERT INTO AUDITAREMPLE VALUES ('SUBIDA DE SALARIO EMPLEADO
'||:OLD.EMPNO||' QUE ERA DE '||:OLD.SAL|| ES DE ||:NEW.SAL);
END;
/

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg.: 14. 4


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

En tercer lugar se intentan modificar los salarios:

UPDATE EMP SET SAL=900


WHERE EMPNO=7788;

1 fila actualizada.

Finalmente observamos el contenido de la tabla AUDITAREMPLE:

SELECT * FROM AUDITAREMPLE;

COL1
----------------------------------------------------
SUBIDA SALARIO EMPLEADO 7788 1140 900

Para restringir la condicin del TRIGGER a solo aquellos registros que satisfagan
cierta condicin lo proporciona la clusula WHEN. En la clusula WHEN el calificador NEW
no necesita ir precedido de dos puntos.

14.5.- DIFERENCIAS ENTRE TRIGGER Y PROCEDURE

TRIGGER PROCEDIMIENTO
CREATE TRIGGER CREATE PROCEDURE
Invocacin implcita. Invocacin explicita.
No admite COMMIT, SAVEPOINT y Si admite COMMIT, SAVEPOINT y
ROLLBACK ROLLBACK .

14.6.- GESTIN Y BORRADO DE TRIGGERS

Para activar o desactivar un TRIGGER se hace con la orden:

ALTER TRIGGER nb_trigger {ENABLE|DISABLE};

Para activar o desactivar los TRIGGERS asociados a una tabla:

ALTER TRIGGER nb_trigger {ENABLE|DISABLE} ALL TRIGGERS;

Para volver a compilar un TRIGGER:

ALTER TRIGGER nb_trigger COMPILE;

Para borrar un TRIGGER:

DROP TRIGGER nb_trigger;

En el diccionario de datos se ven en:

o USER _ OBJECTS

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 14. 5


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

o USER_TRIGGERS;
o DBA_TRIGGERS;

14.7.- PRUEBAS SOBRE TRIGGERS

1. Probar cada una de las operaciones de datos sobre los TRIGGERS, as como las
operaciones sobre otros datos.
2. Probar cada posibilidad de la clusula WHEN.
3. Provocar el disparo.
4. Probar el efecto del TRIGGER sobre otros TRIGGERS que provocarn un evento
hacia la misma tabla.
5. Probar el efecto de otros TRIGGERS sobre el actual.

Ejemplo 1:

Crear un TRIGGER, que se dispare antes de borrar un empleado, guardando sus datos
en la tabla AUDITAREMPLE.

CREATE OR REPLACE TRIGGER AUDITAR_BORRADO_EMPLE


BEFORE DELETE ON EMP
FOR EACH ROW
BEGIN
INSERT INTO AUDITAREMPLE VALUES ('BORRADO EMPLEADO ' || '*'
||:OLD.EMPNO || '*' ||:OLD.ENAME || '*' ||:OLD.DEPTNO);
END;
/

DELETE EMP;
13 FILAS BORRADAS.

SELECT * FROM AUDITAREMPLE;

COL1
----------------------------------------------------------------
BORRADO EMPLEADO *7499*SMITH*30
...

Ejemplo 2:

Crear un TRIGGER en la tabla EMP para calcular la comisin de un vendedor


(SALESMAN) cuando se aade un registro a la tabla EMP o cuando se modifica el salario de
un vendedor, teniendo en cuenta que al insertar la comisin valdr 0 y cuando se modifica si
esta es nula vale cero y si no es nula es la antigua comisin por el nuevo salario entre el
antiguo.

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg.: 14. 6


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

CREATE OR REPLACE TRIGGER CALCULO_COMM


BEFORE INSERT OR UPDATE OF SAL ON EMP
FOR EACH ROW
WHEN (NEW.JOB='SALESMAN')
BEGIN
IF INSERTING THEN :NEW.COMM:=0;
ELSE
IF :OLD.COMM IS NULL THEN
:NEW.COMM:=0;
ELSE
:NEW.COMM:=:OLD.COMM*(:NEW.SAL/:OLD.SAL);
END IF;
END IF;
END;
/

INSERT INTO EMP


VALUES (8888, 'ANTONIO', 'SALESMAN',7900,'',600,'',20);

1 fila creada.

UPDATE EMP
SET SAL = 3000
WHERE EMPNO=7521;

1 fila actualizada.

ROLLBACK;

Rollback terminado.

14.8.- REGLAS QUE GOBIERNAN LOS TRIGGERS.

1.- No leer los datos de una tabla mutante. Una tabla mutante es aquella que
est siendo actualizada mediante sentencias DML, funciones o los efectos de una accin de
integridad referencial (FOREIGN KEY)

Ejemplo:

Crear un TRIGGER que garantice que siempre que se aaden un empleado a una
tabla EMP o se cambie un salario, el salario caiga dentro del establecido por el mximo y
por el mnimo. La condicin del TRIGGER ser que el nuevo trabajo sea distinto de
presidente.

CREATE OR REPLACE TRIGGER CHECK_SAL


BEFORE INSERT OR UPDATE OF SAL, JOB
ON EMP
FOR EACH ROW
WHEN (NEW.JOB<>'PRESIDENT')
DECLARE
V_MINSAL EMP.SAL%TYPE;
V_MAXSAL EMP.SAL%TYPE;
BEGIN
SELECT MIN(SAL), MAX(SAL) INTO
V_MINSAL,V_MAXSAL
FROM EMP WHERE JOB= :NEW.JOB;
IF (:NEW.SAL<V_MINSAL) OR (:NEW.SAL>V_MAXSAL) THEN
RAISE_APPLICATION_ERROR(-20550,'FUERA DE RANGO');

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 14. 7


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

END IF;
END;
/

UPDATE EMP SET SAL= 9000


WHERE EMPNO=7782;
UPDATE EMP SET SAL= 9000
*
ERROR en lnea 1:
ORA-04091: la tabla SCOTT.EMP est mutando, puede que el
disparador/la funcin no puedan verla
ORA-06512: en "SCOTT.CHECK_SAL", lnea 5
ORA-04088: error durante la ejecucin del disparador
'SCOTT.CHECK_SAL'

2.- Combinando datos de una tabla restrictiva. Una tabla es restrictiva cuando
un TRIGGER tiene la necesidad de leer directamente una sentencia SQL o indirectamente
mediante una restriccin de integridad referencial.

Ejemplo:

Crear un TRIGGER que intente actualizar en cascada la clave fornea para los
registros hijos de la tabla EMP, a partir del cambio de la clave primaria de la tabla DEPT.

CREATE OR REPLACE TRIGGER CASCADA_CAMBIOS


AFTER UPDATE OF DEPTNO ON DEPT
FOR EACH ROW
BEGIN
UPDATE EMP SET EMP.DEPTNO = :NEW.DEPTNO
WHERE EMP.DEPTNO = :OLD.DEPTNO;
END;
/

UPDATE DEPT SET DEPTNO=1


WHERE DEPTNO = 30;
UPDATE DEPT SET DEPTNO=1
*
ERROR en lnea 1:
ORA-04091: la tabla SCOTT.DEPT est mutando, puede que el
disparador/la funcin no puedan verla
ORA-06512: en "SCOTT.CASCADA_CAMBIOS", lnea 2
ORA-04088: error durante la ejecucin del disparador
'SCOTT.CASCADA_CAMBIOS'

14.9.- IMPLEMENTACIN DE TRIGGERS

Los TRIGGERS se crean, entre otras razones, por lo siguiente:

Seguridad: permiten el acceso a las tablas segn el valor de los datos.

Auditorias: guardan los valores en otras tablas.

Integridad de datos: implementan reglas complejas de integridad.

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg.: 14. 8


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

Integridad referencial: implementan funcionalidad no estndar.

Replicacin de datos: copian tablas de manera sincronizada a travs de


replicas.

Datos derivados: calculan automticamente valores que se derivan de otros


datos.

Control de eventos: controla los eventos de forma transparente.

14.10.- TRIGGERS SOBRE VISTAS.

Este tipo de TRIGGERS se utilizan para proporcionar la modificacin de vistas que


no podran serlo mediante sentencias SQL.

Ejemplo:

Construir un TRIGGER que permita realizar operaciones de actualizacin en la tabla


DEPT a partir de la vista departamento, el TRIGGER se llamar GEST_DEPART y permitir
insertar, borrar y modificar la localidad de un departamento.

En primer lugar creamos la vista:

CREATE VIEW DEPARTAMENTO AS


SELECT DEPT.DEPTNO, DNAME, LOC, COUNT (EMP.EMPNO) TOT_EMP
FROM EMP, DEPT WHERE EMP.DEPTNO (+) = DEPT.DEPTNO
GROUP BY DEPT.DEPTNO, DNAME, LOC;

En segundo lugar se intenta introducir un registro en la vista, la cual no nos lo


permite por ser compleja:

SQL> INSERT INTO DEPARTAMENTO


2 VALUES (50, 'PRUEBA', 'TOLEDO', 3);
INSERT INTO DEPARTAMENTO
*
ERROR en lnea 1:
ORA-01732: operacin de manipulacin de datos no vlida en esta
vista

En tercer lugar creamos el TRIGGER:

CREATE OR REPLACE TRIGGER GEST_DEPART


INSTEAD OF DELETE OR INSERT OR UPDATE ON DEPARTAMENTO
FOR EACH ROW
BEGIN
IF DELETING THEN
DELETE DEPT WHERE DEPTNO = :OLD.DEPTNO;
ELSIF INSERTING THEN
INSERT INTO DEPT VALUES (:NEW.DEPTNO, :NEW.DNAME, :NEW.LOC);
ELSIF UPDATING ('LOC') THEN
UPDATE DEPT SET LOC = :NEW.LOC
WHERE DEPTNO = :OLD.DEPTNO;
ELSE
RAISE_APPLICATION_ERROR (-20501, 'ERROR');

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 14. 9


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

END IF;
END;
/

En cuarto lugar, probamos a insertar en la tabla a travs de la vista, y como se


observa ms adelante, ya se nos permite pues el TRIGGER ya ha hecho su efecto:

SQL> INSERT INTO DEPARTAMENTO


2 VALUES (50, 'PRUEBA', 'TOLEDO', 3);

1 fila creada.

SQL> SELECT * FROM DEPARTAMENTO;

DEPTNO DNAME LOC TOT_EMP


--------- -------------- ------------- ---------
10 ACCOUNTING NEW YORK 3
20 RESEARCH DALLAS 5
30 SALES CHICAGO 6
40 OPERATIONS BOSTON 0
50 PRUEBA TOLEDO 0

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg.: 14. 10


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

15. MANEJO DE SUBPROGRAMAS.

15.1.- Privilegios del sistema requeridos.


15.2.- Gestin de objetos PL/SQL almacenados.
15.3.- Dependencias.

15.1.- PRIVILEGIOS DEL SISTEMA REQUERIDOS.

Si se quiere crear, modificar, borrar o ejecutar un subprograma PL/SQL, debemos


de tener concedidos los privilegios del sistema apropiados, a menos que utilicemos ANY que
es el privilegio para nuestro propio esquema.

Necesitamos el privilegio EXECUTE para llamar a un subprograma PL/SQL, si no


somos el propietario. Los privilegios del objeto del esquema referenciados en el
subprograma PL/SQL deben concederse explcitamente (no a travs de un rol). El
subprograma PL/SQL se ejecuta bajo el dominio de seguridad del propietario. PROCEDURE
se utiliza para procedimientos almacenados, funciones y paquetes.

Ejemplo:

Acceso directo

GRANT SELECT, INSERT


ON EMP
TO SCOTT;

Acceso indirecto

GRANT EXECUTE
ON HIRE_EMP
TO GREEN;

15.2.- GESTIN DE OBJETOS PL/SQL ALMACENADOS.

Informacin Descripcin Mtodo de acceso


almacenada.
General. Informacin del objeto. Vista USER_OBJECTS del D.D.
Cdigo fuente. Texto del procedimiento. Vista USER_SOURCE y USER_TRIGGERS
del D.D.
SQL*PLUS: editor
Procedure Builder: STORED PROGRAM
UNIT EDITOR.
Parmetros. Modo: IN/OUT/IN OUT, Comando DESCRIBE de SQL*PLUS
tipo de datos.
P_code. Cdigo de objeto compilado. No accesible
Errores de Errores de sintaxis de Vista USER_ERRORS del D.D.
compilacin. PL/SQL. SQL*plus: SHOW ERRORS.
Procedure Builder: COMPILER.

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 15. 1


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

Informacin de Mensajes y variables de DBMS_OUTPUT.


depuracin depuracin especificados por Procedure Builder: INTERPRETE
durante tiempo de el usuario.
ejecucin.

USER_OBJECTS

Columna Descripcin de la columna


OBJECT_NAME Nombre del objeto.
OBJECT_ID Identificador interno para el objeto.
OBJECT_TYPE Tipo de objeto.
CREATED Fecha en que el objeto fue creado.
LAST_DDL_TIME Fecha de su ltima modificacin.
TIMESTAMP Fecha y hora en que el objeto fue recompilado por
ltima vez.
STATUS VALID o INVALID.

SELECT OBJECT_NAME, OBJECT_TYPE


FROM USER_OBJECTS
WHERE OBJECT_TYPE IN (PROCEDURE, FUNCTION)
ORDER BY OBJECT_NAME

USER_SOURCE

Columna Descripcin de la columna


NAME Nombre del objeto.
TYPE Tipo de objeto.
LINE Nmero de lnea del cdigo fuente.
TEXT Texto de la lnea del cdigo fuente.

SELECT TEXT
FROM USER_SOURCE
WHERE NAME = QUERY_EMP
ORDER BY LINE;

USER_ERRORS

Columna Descripcin de la columna


NAME Nombre del objeto.
TYPE Tipo de objeto.
SEQUENCE Nmero de secuencia, para ordenar.
LINE Nmero de lnea del cdigo fuente donde ocurre el
error.
POSITION Posicin del error en la lnea.
TEXT Texto del mensaje de error.

SELECT LINE||/|| POSITION POS, TEXT


FROM USER_ERRORS
WHERE NAME = LOG_EXECUTION
ORDER BY LINE;

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 15. 2


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

SHOW ERRORS

SHOW ERRORS PROCEDURE LOG_EXECUTION;

USER_TRIGGERS

Columna Descripcin de la columna


TRIGGER_NAME Nombre del trigger.
TRIGGER_TYPE El tipo es BEFORE, AFTER o INSTEAD OF.
TRIGGERING_EVENT La operacin DML asociada al trigger.
TABLE_NAME Nombre de la tabla de la BD.
REFERENCING_NAMES Nombre utilizado para :OLD y :NEW.
WHEN_CLAUSE Clusula WHEN utilizada.
STATUS Estado del trigger.
TRIGGER_BODY Accin a llevar a cabo.

15.3.- DEPENDENCIAS.

OBJETOS DEPENDIENTES OBJETOS REFERENCIADOS

VIEW TABLE
PROCEDURE VIEW
FUNCTION SEQUENCE
PACKAGE SPECIFICATION SYNONYM
PACKAGE BODY PROCEDURE
DATABASE TRIGGER FUNCTION
PACKAGE SPECIFICATION

Algunos objetos referencian a otros objetos como parte de su definicin. Por


ejemplo, un procedimiento almacenado podra contener una sentencia SELECT que
selecciona columnas de una tabla, por esta razn, el procedimiento almacenado se llama
objeto dependiente, mientras que una tabla se llama objeto referenciado.

Emisin de dependencia

Si alteramos la definicin de un objeto referenciado, los objetos dependientes podran o


no continuar funcionando correctamente. En el escenario de arriba, si se cambia la
definicin de la tabla, el procedimiento podra o no seguir funcionado sin error.

Oracle Server registra automticamente las dependencias entre los objetos. Para
manejar dependencias, todos los objetos del esquema tienen un estatus (vlido o invlido) el
cual es registrado en el diccionario de datos.

Status Significado
VALID El objeto ha sido compilado y puede ser utilizado inmediatamente
cuando se referencia
INVALID El objeto tiene que ser compilado entes de que pueda ser
utilizado.

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 15. 3


Desarrollo de aplicaciones en entornos de 4 generacin y con herramientas CASE

Dependencias USER_DEPENDECIES

SELECT, NAME, TYPE, REFERENCED_NAME, REFERENCED_TYPE


FROM USER_DEPENDENCIES
WHERE REFERENCED_NAME IN (EMP, NEW_EMP);

Para visualizar dependencias directas utilizando USER_DEPENDENCIES hay que


determinar qu objetos de la base de datos se recopilan automticamente mediante la
visualizacin de dependencias directas en esta vista del D.D.

Tambin las dependencias se pueden ver en las ALL_DEPENDENCIES y


DBA_DEPENDENCIES, cada una de las cuales contiene la columna adicional OWNER para
ver quien es el propietario del objeto.

Columna Descripcin
NAME Nombre del objeto dependiente
TYPE Tipo del objeto dependiente
REFERENCED_OWNER Esquema del objeto referenciado
REFERENCED_NAME Nombre del objeto referenciado
REFERENCED_TYPE Tipo del objeto referenciado
REFERENCED_LINK_NAME DATABASE LINK para acceder a los objetos
referenciados

Bloque IV Desarrollo de aplicaciones con PL/SQL Pg: 15. 4

Vous aimerez peut-être aussi