Está en la página 1de 25

PL SQL

SQL es un lenguaje de consulta para los sistemas de bases de datos relaciónales, pero que no
posee la potencia de los lenguajes de programación.

Para abordar el presente tutorial con mínimo de garantías es necesario conocer


previamente SQL.

Podemos acceder a un completo tutorial de SQL desde AQUI.

PL/SQL amplia SQL con los elementos caracteristicos de los lenguajes de programación,
variables, sentencias de control de flujo, bucles ...

Cuando se desea realizar una aplicación completa para el manejo de una base de datos
relacional, resulta necesario utilizar alguna herramienta que soporte la capacidad de
consulta del SQL y la versatilidad de los lenguajes de programación tradicionales. PL/SQL es
el lenguaje de programación que proporciona Oracle para extender el SQL estándar con
otro tipo de instrucciones.

¿Qué vamos a necesitar?

Para poder seguir este tutorial correctamente necesitaremos tener los siguientes
elementos:

 Una instancia de ORACLE 8i o superior funcionando correctamente.


 Herramientas cliente de ORACLE, en particular SQL*Plus para poder ejecutar los
ejemplo.
 Haber configurado correctamente una conexión a ORACLE.

Introducción
SQL es un lenguaje de consulta para los sistemas de bases de datos relaciónales, pero que no
posee la potencia de los lenguajes de programación. No permite el uso de
variables, estructuras de control de flujo, bucles ... y demás elementos característicos de la
programación. No es de extrañar, SQL es un lenguaje de consulta, no un lenguaje de
programación.

Sin embargo, SQL es la herramienta ideal para trabajar con bases de datos. Cuando
se desea realizar una aplicación completa para el manejo de una base de datos
relacional, resulta necesario utilizar alguna herramienta que soporte la capacidad de
consulta del SQL y la versatilidad de los lenguajes de programación tradicionales.
PL/SQL es el lenguaje de programación que proporciona Oracle para extender el SQL
estándar con otro tipo de instrucciones y elementos propios de los lenguajes de
programación.

1
Con PL/SQL vamos a poder programar las unidades de programa de la base de datos ORACLE,
están son:

 Procedimientos almacenados
 Funciones
 Triggers
 Scripts

Pero además PL/SQL nos permite realizar programas sobre las siguientes herramientas de
ORACLE:

 Oracle Forms
 Oracle Reports
 Oracle Graphics
 Oracle Aplication Server

Fundamentos de PL/SQL

Primeros pasos con PL/SQL


Para programar en PL/SQL es necesario conocer sus fundamentos.

Como introducción vamos a ver algunos elementos y conceptos básicos del lenguaje.

 PL/SQL no es CASE-SENSITIVE, es decir, no diferencia mayúsculas de minúsculas


como otros lenguajes de programación como C o Java. Sin embargo debemos
recordar que ORACLE es CASE-SENSITIVE en las búsquedas de texto.
 Una línea en PL/SQL contiene grupos de caracteres conocidos como UNIDADES
LEXICAS, que pueden ser clasificadas como:
o DELIMITADORES
o IDENTIFICADORES
o LITERALES
o COMENTARIOS
o EXPRESIONES
 DELIMITADOR: Es un símbolo simple o compuesto que tiene una función especial
en PL/SQL. Estos pueden ser:
o Operadores Aritméticos
o Operadores Lógicos
o Operadores Relacionales
 IDENTIFICADOR: Son empleados para nombrar objetos de programas en PL/SQL asi
como a unidades dentro del mismo, estas unidades y objetos incluyen:
o Constantes
o Cursores
o Variables
o Subprogramas
o Excepciones
o Paquetes
 LITERAL: Es un valor de tipo numérico, carácter, cadena o lógico no representado
por un identificador (es un valor explícito).
2
 COMENTARIO: Es una aclaración que el programador incluye en el código. Son
soportados 2 estilos de comentarios, el de línea simple y de multilínea, para lo cual
son empleados ciertos caracters especiales como son:

-- Linea simple

/*
Conjunto de Lineas
*/

Tipos de datos en PL/SQL


Cada constante y variable tiene un tipo de dato en el cual se especifica el formato de
almacenamiento, restricciones y rango de valores válidos.

PL/SQL proporciona una variedad predefinida de tipos de datos. Casi todos los tipos de datos
manejados por PL/SQL son similares a los soportados por SQL. A continuación se muestran
los TIPOS de DATOS más comunes:

 NUMBER (Numérico): Almacena números enteros o de punto flotante, virtualmente


de cualquier longitud, aunque puede ser especificada la precisión (Número de
dígitos) y la escala que es la que determina el número de decimales.

-- NUMBER [(precision, escala)]

saldo NUMBER(16,2); /* Indica que puede almacenar un valor numérico de 16


posiciones, 2 de ellas decimales. Es decir, 14 enteros y dos decimales */

 CHAR (Caracter): Almacena datos de tipo caracter con una longitud maxima de
32767 y cuyo valor de longitud por default es 1

-- CHAR [(longitud_maxima)]

nombre CHAR(20) /* Indica que puede almacenar valores alfanuméricos de 20


posiciones */

 VARCHAR2 (Caracter de longitud variable): Almacena datos de tipo caracter


empleando sólo la cantidad necesaria aún cuando la longitud máxima sea mayor.

-- VARCHAR2 (longitud_maxima)

nombre VARCHAR2(20);
/* Indica que puede almacenar valores alfanuméricos de hasta 20
posiciones */
/* Cuando la longitud de los datos sea menor de 20 no se
rellena con blancos */

3
 BOOLEAN (lógico): Se emplea para almacenar valores TRUE o FALSE.

hay_error BOOLEAN;

 DATE (Fecha): Almacena datos de tipo fecha. Las fechas se almacenan internamente
como datos numéricos, por lo que es posible realizar operaciones aritméticas con
ellas.

 Atributos de tipo. Un atributo de tipo PL/SQL es un modificador que puede ser usado
para obtener información de un objeto de la base de datos. El atributo %TYPE permite
conocer el tipo de una variable, constante o campo de la base de datos. El atributo
%ROWTYPE permite obtener los tipos de todos los campos de una tabla de la base de
datos, de una vista o de un cursor.

 PL/SQL también permite la creación de tipos personalizados (registros) y


colecciones (tablas de PL/SQL), que veremos en sus apartados correspondientes.

Existen por supuesto más tipos de datos, la siguiente tabla los muestra:

Tipo de
dato / Oracle 8i Oracle 9i Descripción
Sintáxis
Donde p es la precisión y e la
escala.
La precisión máxima La precisión máxima
dec(p, e) Por ejemplo: dec(3,1) es un
es de 38 dígitos. es de 38 dígitos.
número que tiene 2 dígitos
antes del decimal y un dígito
después del decimal.
Donde p es la precisión y e la
escala.
decimal(p, La precisión máxima La precisión máxima
Por ejemplo: decimal(3,1) es
e) es de 38 dígitos. es de 38 dígitos.
un número que tiene 2 dígitos
antes del decimal y un dígito
después del decimal.
double
precision
float

4
int
integer
Donde p es la precisión y e la
escala.
numeric(p, La precisión máxima La precisión máxima
Por ejemplo: numeric(7,2) es
e) es de 38 dígitos. es de 38 dígitos.
un número que tiene 5 dígitos
antes del decimal y 2 dígitos
después del decimal.
Donde p es la precisión y e la
escala.
number(p, La precisión máxima La precisión máxima
Por ejemplo: number(7,2) es
e) es de 38 dígitos. es de 38 dígitos.
un número que tiene 5 dígitos
antes del decimal y 2 dígitos
después del decimal.
real
smallint
Hasta 32767 bytes en Hasta 32767 bytes en
Donde tamaño es el número
PLSQL. PLSQL.
char de caracteres a almacenar.
(tamaño) Son cadenas de ancho fijo. Se
Hasta 2000 bytes en Hasta 2000 bytes en
rellena con espacios.
Oracle 8i. Oracle 9i.
Hasta 32767 bytes en Hasta 32767 bytes en
Donde tamaño es el número
PLSQL. PLSQL.
varchar2 de caracteres a almacenar.
(tamaño) Son cadenas de ancho
Hasta 4000 bytes en Hasta 4000 bytes en
variable.
Oracle 8i. Oracle 9i.
Son cadenas de ancho
long Hasta 2 gigabytes. Hasta 2 gigabytes.
variable.
Hasta 32767 bytes en Hasta 32767 bytes en
PLSQL. PLSQL.
Son cadenas binarias de ancho
raw
variable.
Hasta 2000 bytes en Hasta 2000 bytes en
Oracle 8i. Oracle 9i.
Son cadenas binarias de ancho
long raw Hasta 2 gigabytes. Hasta 2 gigabytes.
variable.
Una fecha entre el 1 Una fecha entre el 1
de Enero de 4712 A.C. de Enero de 4712 A.C.
date
y el 31 de Diciembre y el 31 de Diciembre
de 9999 D.C. de 9999 D.C.

5
fractional seconds
timestamp Incluye año, mes día, hora,
precision debe ser un
(fractional No soportado por minutos y segundos.
número entre 0 y 9.
seconds Oracle 8i.
(El valor por defecto
precision) Por ejemplo: timestamp(6)
es 6)
Incluye año, mes día, hora,
timestamp
fractional seconds minutos y segundos; con un
(fractional
precision debe ser un valor de desplazamiento de
seconds No soportado por
número entre 0 y 9. zona horaria.
precision) Oracle 8i.
(El valor por defecto
with time
es 6) Por ejemplo: timestamp(5)
zone
with time zone
Incluye año, mes día, hora,
timestamp
fractional seconds minutos y segundos; con una
(fractional
precision debe ser un zona horaria expresada como
seconds No soportado por
número entre 0 y 9. la zona horaria actual.
precision) Oracle 8i.
(El valor por defecto
with local
es 6) Por ejemplo: timestamp(4)
time zone
with local time zone
Período de tiempo
interval year precision debe
almacenado en años y meses.
year (year No soportado por ser un número entre 0
precision) Oracle 8i. y 9. (El valor por
Por ejemplo: interval year(4)
to month defecto es 2)
to month
day precision debe
ser un número entre 0
interval
y 9. (El valor por
day (day Incluye año, mes día, hora,
defecto es 2)
precision) minutos y segundos.
No soportado por
to second
Oracle 8i. fractional seconds
(fractional Por ejemplo: interval day(2) to
precision debe ser un
seconds second(6)
número entre 0 y 9.
precision)
(El valor por defecto
es 6)
El formato del campo El formato del campo
rowid es: rowid es:

BBBBBBB.RRRR.FFFFF BBBBBBB.RRRR.FFFFF
Datos binarios de ancho fijo.
donde BBBBBBB es el donde BBBBBBB es el
Cada registro de la base de
rowid bloque en el fichero bloque en el fichero
datos tiene una dirección
de la base de datos; de la base de datos;
física o rowid.
RRRR es la fila del RRRR es la fila del
bloque; FFFFF es el bloque; FFFFF es el
fichero de la base de fichero de la base de
datos. datos.

6
urowid Rowid universal. Donde
Hasta 2000 bytes. Hasta 2000 bytes.
[tamaño] tamaño es opcional.
Válido en PLSQL, este Válido en PLSQL, este
boolean tipo de datos no tipo de datos no
existe en Oracle 8i. existe en Oracle 9i.
Hasta 32767 bytes en Hasta 32767 bytes en Donde tamaño es el número
nchar
PLSQL. Hasta 2000 PLSQL. Hasta 2000 de caracteres a almacenar.
(tamaño)
bytes en Oracle 8i. bytes en Oracle 9i. Cadena NLS de ancho fijo.
Donde tamaño es el número
Hasta 32767 bytes en Hasta 32767 bytes en
nvarchar2 de caracteres a almacenar.
PLSQL. Hasta 4000 PLSQL. Hasta 4000
(tamaño) Cadena NLS de ancho
bytes en Oracle 8i. bytes en Oracle 9i.
variable.
Localizadores de archivo
apuntan a un objeto binario
bfile Hasta 4 gigabytes. Hasta 4 gigabytes.
de sólo lectura fuera de la
base de datos.
Localizadores LOB apuntan a
blob Hasta 4 gigabytes. Hasta 4 gigabytes. un gran objeto binario dentro
de la base de datos.
Localizadores LOB apuntan a
clob Hasta 4 gigabytes. Hasta 4 gigabytes. un gran objeto de caracteres
dentro de la base de datos.
Localizadores LOB apuntan a
un gran objeto NLS de
nclob Hasta 4 gigabytes. Hasta 4 gigabytes.
caracteres dentro de la base
de datos.

La siguiente tabla ilustra los operadores de PL/SQL.

Tipo de operador Operadores


Operador de asignación := (dos puntos + igual)
Operadores aritméticos + (suma)
- (resta)
* (multiplicación)
/ (división)
** (exponente)
Operadores relacionales o = (igual a)
de comparación <> (distinto de)
< (menor que)
> (mayor que)
>= (mayor o igual a)
<= (menor o igual a)

7
Operadores lógicos AND (y lógico)
NOT (negacion)
OR (o lógico)
Operador de
||
concatenación

Estructuras de control en PL/SQL

Estructuras de control de flujo


En PL/SQL solo disponemos de la estructura condicional IF. Su sintaxis se muestra a
continuación:

IF (expresion) THEN
-- Instrucciones
ELSIF (expresion) THEN
-- Instrucciones
ELSE
-- Instrucciones
END IF;

Un aspecto a tener en cuenta es que la instrucción condicional anidada es ELSIF y no


"ELSEIF".

Sentencia GOTO
PL/SQL dispone de la sentencia GOTO. La sentencia GOTO desvía el flujo de ejecución a una
determinada etiqueta.

En PL/SQL las etiquetas se indican del siguiente modo: << etiqueta >>

El siguiente ejemplo ilustra el uso de GOTO.

DECLARE
flag NUMBER;
BEGIN
flag :=1 ;

8
IF (flag = 1) THEN
GOTO paso2;
END IF;
<<paso1>>
dbms_output.put_line('Ejecucion de paso 1');
<<paso2>>
dbms_output.put_line('Ejecucion de paso 2');
END;

Bucles
En PL/SQL tenemos a nuestra disposición los siguientes iteradores o bucles:

 LOOP
 WHILE
 FOR

El bucle LOOP, se repite tantas veces como sea necesario hasta que se fuerza su salida con la
instrucción EXIT. Su sintaxis es la siguiente

LOOP
-- Instrucciones
IF (expresion) THEN
-- Instrucciones
EXIT;
END IF;
END LOOP;

El bucle WHILE, se repite mientras que se cumpla expresion.

WHILE (expresion) LOOP


-- Instrucciones
END LOOP;

El bucle FOR, se repite tanta veces como le indiquemos en los identificadores inicio y final.

FOR contador IN [REVERSE] inicio..final LOOP

-- Instrucciones

END LOOP;

9
En el caso de especificar REVERSE el bucle se recorre en sentido inverso.

Bloques PL/SQL
Un programa de PL/SQL está compuesto por bloques. Un programa está compuesto como
mínimo de un bloque.

Los bloques de PL/SQL pueden ser de los siguientes tipos:

 Bloques anónimos
 Subprogramas

10
Estructura de un Bloque
Los bloques PL/SQL presentan una estructura específica compuesta de tres partes bien
diferenciadas:

 La sección declarativa en donde se declaran todas las constantes y variables que se


van a utilizar en la ejecución del bloque.
 La sección de ejecución que incluye las instrucciones a ejecutar en el bloque PL/SQL.
 La sección de excepciones en donde se definen los manejadores de errores que
soportará el bloque PL/SQL.

Cada una de las partes anteriores se delimita por una palabra reservada, de modo que un
bloque PL/SQL se puede representar como sigue:

[ declare | is | as ]
/*Parte declarativa*/
begin
/*Parte de ejecucion*/
[ exception ]
/*Parte de excepciones*/
end;

De las anteriores partes, únicamente la sección de ejecución es obligatoria, que quedaría


delimitada entre las cláusulas BEGIN y END. Veamos un ejemplo de bloque PL/SQL muy
genérico. Se trata de un bloque anónimos, es decir no lo identifica ningún nombre. Los
bloques anónimos identifican su parte declarativa con la palabra reservada DECLARE.

DECLARE
/*Parte declarativa*/
nombre_variable DATE;
BEGIN
/*Parte de ejecucion
* Este código asigna el valor de la columna
"nombre_columna"
* a la variable identificada por "nombre_variable"
*/
SELECT SYSDATE
INTO nombre_variable
FROM DUAL;

EXCEPTION
/*Parte de excepciones*/
WHEN OTHERS THEN
dbms_output.put_line('Se ha producido un error');
END;

11
A continuación vamos a ver cada una de estas secciones

Sección de Declaración de Variables


En esta parte se declaran las variables que va a necesitar nuestro programa. Una variable se
declara asignándole un nombre o "identificador" seguido del tipo de valor que puede
contener. También se declaran cursores, de gran utilidad para la consulta de datos, y
excepciones definidas por el usuario. También podemos especificar si se trata de una
constante, si puede contener valor nulo y asignar un valor inicial.

La sintaxis genérica para la declaracion de constantes y variables es:

nombre_variable [CONSTANT] <tipo_dato> [NOT NULL][:=valor_inicial]

donde:

 tipo_dato: es el tipo de dato que va a poder almacenar la variable, este puede ser
cualquiera de los tipos soportandos por ORACLE, es decir NUMBER , DATE , CHAR ,
VARCHAR, VARCHAR2, BOOLEAN ... Además para algunos tipos de datos (NUMBER
y VARCHAR) podemos especificar la longitud.
 La cláusula CONSTANT indica la definición de una constante cuyo valor no puede ser
modificado. Se debe incluir la inicialización de la constante en su declaración.
 La cláusula NOT NULL impide que a una variable se le asigne el valor nulo, y por tanto
debe inicializarse a un valor diferente de NULL.
 Las variables que no son inicializadas toman el valor inicial NULL.
 La inicialización puede incluir cualquier expresión legal de PL/SQL, que lógicamente
debe corresponder con el tipo del identificador definido.
 Los tipos escalares incluyen los definidos en SQL más los tipos VARCHAR y BOOLEAN.
Este último puede tomar los valores TRUE, FALSE y NULL, y se suele utilizar para
almacenar el resultado de alguna operación lógica. VARCHAR es un sinónimo de
CHAR.
 También es posible definir el tipo de una variable o constante, dependiendo del tipo
de otro identificador, mediante la utilización de las cláusulas %TYPE y %ROWTYPE.
Mediante la primera opción se define una variable o constante escalar, y con la
segunda se define una variable fila, donde identificador puede ser otra variable fila o
una tabla. Habitualmente se utiliza %TYPE para definir la variable del mismo tipo que
tenga definido un campo en una tabla de la base de datos, mientras que %ROWTYPE
se utiliza para declarar variables utilizando cursores.

12
Ejemplos:

Estructura de un bloque anónimo.

DECLARE
/* Se declara la variable de tipo VARCHAR2(15)
identificada por v_location y se le asigna
el valor "Granada"*/

v_location VARCHAR2(15) := ’Granada’;

/*Se declara la constante de tipo


NUMBER identificada por PI y se le asigna
el valor 3.1416*/
PI CONSTANT NUMBER := 3.1416;

/*Se declara la variable del mismo tipo


que tenga el campo nombre de la tabla tabla_empleados
identificada por v_nombre y no se le asigna ningún
valor */
v_nombre tabla_empleados.nombre%TYPE;

/*Se declara la variable del tipo


registro correspondiente a un supuesto cursor, llamado
micursor, identificada por reg_datos*/
reg_datos micursor%ROWTYPE;

BEGIN
/*Parte de ejecucion*/
EXCEPTION
/*Parte de excepciones*/
END;

13
Estructura de un subprograma:

CREATE PROCEDURE simple_procedure IS


/* Se declara la variable de tipo VARCHAR2(15)
identificada por v_location y se le asigna
el valor "Granada"*/

v_location VARCHAR2(15) := ’Granada’;

/*Se declara la constante de tipo


NUMBER identificada por PI y se le asigna
el valor 3.1416*/
PI CONSTANT NUMBER := 3.1416;

/*Se declara la variable del mismo tipo


que tenga el campo nombre de la tabla tabla_empleados
identificada por v_nombre y no se le asigna ningún
valor */
v_nombre tabla_empleados.nombre%TYPE;

/*Se declara la variable del tipo


registro correspondiente a un supuesto cursor, llamado
micursor, identificada por reg_datos*/
reg_datos micursor%ROWTYPE;

BEGIN
/*Parte de ejecucion*/
EXCEPTION
/*Parte de excepciones*/
END;

14
Cursores en PL/SQL

Introducción a cursores PL/SQL


PL/SQL utiliza cursores para gestionar las instrucciones SELECT. Un cursor es un conjunto
de registros devuelto por una instrucción SQL. Técnicamente los cursores son fragmentos
de memoria que reservados para procesar los resultados de una consulta SELECT.

Podemos distinguir dos tipos de cursores:

 Cursores implícitos. Este tipo de cursores se utiliza para operaciones SELECT INTO.
Se usan cuando la consulta devuelve un único registro.
 Cursores explícitos. Son los cursores que son declarados y controlados por el
programador. Se utilizan cuando la consulta devuelve un conjunto de registros.
Ocasionalmente también se utilizan en consultas que devuelven un único registro
por razones de eficiencia. Son más rápidos.

Un cursor se define como cualquier otra variable de PL/SQL y debe nombrarse de acuerdo a
los mismos convenios que cualquier otra variable. Los cursores implícitos no necesitan
declaración.

El siguiente ejemplo declara un cursor explícito:

declare
cursor c_paises is
SELECT CO_PAIS, DESCRIPCION
FROM PAISES;
begin
/* Sentencias del bloque ...*/
end;

Para procesar instrucciones SELECT que devuelvan más de una fila, son necesarios cursores
explícitos combinados con un estructura de bloque.

Un cursor admite el uso de parámetros. Los parámetros deben declararse junto con el
cursor.

El siguiente ejemplo muestra la declaración de un cursor con un parámetro, identificado por


p_continente.

declare
cursor c_paises (p_continente IN VARCHAR2) is
SELECT CO_PAIS, DESCRIPCION
FROM PAISES

WHERE CONTINENTE = p_continente;


begin

15
/* Sentencias del bloque ...*/
end;

El siguiente diagrama representa como se procesa una instrucción SQL a través de un


cursor.

Fases para procesar una instrucción SQL

Cursores Implícitos

Declaración de cursores implícitos.

Los cursores implícitos se utilizan para realizar consultas SELECT que devuelven un único
registro.

Deben tenerse en cuenta los siguientes puntos cuando se utilizan cursores implícitos:

 Con cada cursor implícito debe existir la palabra clave INTO.


 Las variables que reciben los datos devueltos por el cursor tienen que contener el
mismo tipo de dato que las columnas de la tabla.
 Los cursores implícitos solo pueden devolver una única fila. En caso de que se
devuelva más de una fila (o ninguna fila) se producirá una excepción. No se
preocupe si aún no sabe que es una excepción, le valdrá conocer que es el medio
por el que PL/SQL gestiona los errores.

El siguiente ejemplo muestra un cursor implicito:

declare
vdescripcion VARCHAR2(50);
begin
SELECT DESCRIPCION
INTO vdescripcion
from PAISES
WHERE CO_PAIS = 'ESP';

dbms_output.put_line('La lectura del cursor es: '


16
|| vdescripcion);

end;

La salida del programa generaría la siguiente línea:

La lectura del cursor es: ESPAÑA

Excepciones asociadas a los cursores implicitos.

Los cursores implicitos sólo pueden devolver una fila, por lo que pueden producirse
determinadas excepciones. Las más comunes que se pueden encontrar son no_data_found
y too_many_rows. La siguiente tabla explica brevemente estas excepciones.

Excepcion Explicacion
NO_DATA_FOUND Se produce cuando una sentencia SELECT intenta recuperar datos pero
ninguna fila satisface sus condiciones. Es decir, cuando "no hay datos"
TOO_MANY_ROWS Dado que cada cursor implicito sólo es capaz de recuperar una fila , esta
excepcion detecta la existencia de más de una fila.

Cursores Explicitos en PL/SQL

Declaración de cursores explícitos

Los cursores explícitos se emplean para realizar consultas SELECT que pueden devolver
cero filas, o más de una fila.

Para trabajar con un cursor explicito necesitamos realizar las siguientes tareas:

1. Declarar el cursor.
2. Abrir el cursor con la instrucción OPEN.
3. Leer los datos del cursor con la instrucción FETCH.
4. Cerrar el cursor y liberar los recursos con la instrucción CLOSE.

Para declarar un cursor debemos emplear la siguiente sintaxis:

CURSOR nombre_cursor IS

instrucción_SELECT

También debemos declarar los posibles parametros que requiera el cursor:

17
CURSOR nombre_cursor(param1 tipo1, ..., paramN tipoN) IS

instrucción_SELECT

Para abrir el cursor

OPEN nombre_cursor;

o bien (en el caso de un cursor con parámetros)

OPEN nombre_cursor(valor1, valor2, ..., valorN);

Para recuperar los datos en variables PL/SQL.

FETCH nombre_cursor INTO lista_variables;

-- o bien ...

FETCH nombre_cursor INTO registro_PL/SQL;

Para cerrar el cursor:

CLOSE nombre_cursor;

El siguiente ejemplo ilustra el trabajo con un cursor explícito. Hay que tener en cuenta que
al leer los datos del cursor debemos hacerlo sobre variables del mismo tipo de datos de la
tabla (o tablas) que trata el cursor.

DECLARE
CURSOR cpaises
IS
SELECT CO_PAIS, DESCRIPCION, CONTINENTE
FROM PAISES;

co_pais VARCHAR2(3);
descripcion VARCHAR2(50);
continente VARCHAR2(25);
18
BEGIN
OPEN cpaises;
FETCH cpaises INTO co_pais,descripcion,continente;
CLOSE cpaises;
END;

Podemos simplificar el ejemplo utilizando el atributo de tipo %ROWTYPE sobre el cursor.

DECLARE
CURSOR cpaises
IS
SELECT CO_PAIS, DESCRIPCION, CONTINENTE
FROM PAISES;

registro cpaises%ROWTYPE;
BEGIN
OPEN cpaises;
FETCH cpaises INTO registro;
CLOSE cpaises;
END;

El mismo ejemplo, pero utilizando parámetros:

DECLARE
CURSOR cpaises (p_continente VARCHAR2)
IS
SELECT CO_PAIS, DESCRIPCION, CONTINENTE
FROM PAISES
WHERE CONTINENTE = p_continente;

registro cpaises%ROWTYPE;
BEGIN
OPEN cpaises('EUROPA');
FETCH cpaises INTO registro;
CLOSE cpaises;
END;

Cuando trabajamos con cursores debemos considerar:

 Cuando un cursor está cerrado, no se puede leer.

19
 Cuando leemos un cursor debemos comprobar el resultado de la lectura utilizando
los atributos de los cursores.
 Cuando se cierra el cursor, es ilegal tratar de usarlo.
 Es ilegal tratar de cerrar un cursor que ya está cerrado o no ha sido abierto

Atributos de cursores
Toman los valores TRUE, FALSE o NULL dependiendo de la situación:

Atributo Antes de abrir Al abrir Durante la recuperación Al finalizar la recuperación Después de cerrar
%NOTFOUND ORA-1001 NULL FALSE TRUE ORA-1001
%FOUND ORA-1001 NULL TRUE FALSE ORA-1001
%ISOPEN FALSE TRUE TRUE TRUE FALSE
%ROWCOUNT ORA-1001 0 * ** ORA-1001

* Número de registros que ha recuperado hasta el momento


** Número de total de registros

Manejo del cursor


Por medio de ciclo LOOP podemos iterar a través del cursor. Debe tenerse cuidado de
agregar una condición para salir del bucle:

Vamos a ver varias formas de iterar a través de un cursor. La primera es utilizando un bucle
LOOP con una sentencia EXIT condicionada:

OPEN nombre_cursor;

LOOP

FETCH nombre_cursor INTO lista_variables;

EXIT WHEN nombre_cursor%NOTFOUND;

/* Procesamiento de los registros recuperados */

END LOOP;

CLOSE nombre_cursor;

20
21
Aplicada a nuestro ejemplo anterior:

DECLARE
CURSOR cpaises
IS
SELECT CO_PAIS, DESCRIPCION, CONTINENTE
FROM PAISES;

co_pais VARCHAR2(3);
descripcion VARCHAR2(50);
continente VARCHAR2(25);
BEGIN
OPEN cpaises;
LOOP
FETCH cpaises INTO
co_pais,descripcion,continente;
EXIT WHEN cpaises%NOTFOUND;
dbms_output.put_line(descripcion);
END LOOP;
CLOSE cpaises;
END;

Otra forma es por medio de un bucle WHILE LOOP. La instrucción FECTH aparece dos veces.

OPEN nombre_cursor;

FETCH nombre_cursor INTO lista_variables;

WHILE nombre_cursor%FOUND
LOOP

/* Procesamiento de los registros recuperados */

FETCH nombre_cursor INTO lista_variables;

END LOOP;

CLOSE nombre_cursor;

22
DECLARE
CURSOR cpaises
IS
SELECT CO_PAIS, DESCRIPCION, CONTINENTE
FROM PAISES;

co_pais VARCHAR2(3);
descripcion VARCHAR2(50);
continente VARCHAR2(25);
BEGIN
OPEN cpaises;
FETCH cpaises INTO co_pais,descripcion,continente;
WHILE cpaises%found
LOOP
dbms_output.put_line(descripcion);
FETCH cpaises INTO co_pais,descripcion,continente;
END LOOP;
CLOSE cpaises;
END;

Por último podemos usar un bucle FOR LOOP. Es la forma más corta ya que el cursor es
implicitamente se ejecutan las instrucciones OPEN, FECTH y CLOSE.

FOR variable IN nombre_cursor LOOP

/* Procesamiento de los registros recuperados */

END LOOP;

BEGIN
FOR REG IN (SELECT * FROM PAISES)
LOOP
dbms_output.put_line(reg.descripcion);
END LOOP;
END;

23
Cursores de actualización

Declaración y utiización de cursores de actualización.

Los cursores de actualización se declaran igual que los cursores explícitos, añadiendo FOR
UPDATE al final de la sentencia select.

CURSOR nombre_cursor IS
instrucción_SELECT
FOR UPDATE

Para actualizar los datos del cursor hay que ejecutar una sentencia UPDATE especificando la
cláusula WHERE CURRENT OF <cursor_name>.

UPDATE <nombre_tabla> SET


<campo_1> = <valor_1>
[,<campo_2> = <valor_2>]
WHERE CURRENT OF <cursor_name>

El siguiente ejemplo muestra el uso de un curso de actualización:

DECLARE
CURSOR cpaises IS
select CO_PAIS, DESCRIPCION, CONTINENTE
from paises
FOR UPDATE;
co_pais VARCHAR2(3);
descripcion VARCHAR2(50);
continente VARCHAR2(25);
BEGIN
OPEN cpaises;
FETCH cpaises INTO co_pais,descripcion,continente;
WHILE cpaises%found
LOOP
UPDATE PAISES
SET CONTINENTE = CONTINENTE || '.'
WHERE CURRENT OF cpaises;

FETCH cpaises INTO co_pais,descripcion,continente;


END LOOP;
CLOSE cpaises;
COMMIT;

END;

Cuando trabajamos con cursores de actualización debemos tener en cuenta las siguientes
consideraciones:

Los cursores de actualización generan bloqueos en la base de datos.


24
25

También podría gustarte