You are on page 1of 11

Construyendo con Bloques en PL/SQL

Por Steven Feuerstein Oracle Ace


Traducido por Alfonso Vicente
Publicado en marzo 2012
Publicado en
Marzo/Abril 2011
Parte 1 en una serie de artculos sobre la comprensin y uso de PL/SQL
El lenguaje PL/SQL de Oracle celebr su cumpleaos nmero 22 en 2011. Lo s porque estoy
mirando la primera gua del usuario de Oracle PL/SQL que se haya publicado, es de
la versin 1.0 de PL/SQL, y su fecha de publicacin es Setiembre de 1989. Estaba tr
abajando para Oracle en ese momento, construyendo las primeras herramientas de a
utomatizacin utilizadas por la fuerza de ventas de Oracle EE.UU. Ya haba trabajado
con PL/SQL dentro de SQL Forms 3.0, pero fue con el lanzamiento de la base de d
atos Oracle 6, que PL/SQL estuvo disponible como un lenguaje independiente para
desarrollo de aplicaciones.
Tres aos ms tarde, escrib mi primer libro sobre PL/SQL y desde entonces he estudiad
o este lenguaje, he desarrollado montones y montones de cdigo PL/SQL, y he escrit
o sobre este excelente lenguaje de programacin de base de datos. Por supuesto, yo
no era el nico. Miles de desarrolladores en todo el mundo han construido una mul
titud de aplicaciones basadas en Oracle PL/SQL en las dcadas desde que se liber.
Lo mejor de todo es que sigue habiendo un flujo constante de nuevos desarrollado
res PL/SQL. De hecho, con la aparicin relativamente reciente de la India, China y
otras naciones como potencias de tecnologa, he visto a toda una nueva generacin d
e desarrolladores descubrir PL/SQL y trabajar para dominarlo.
Para ayudar a que los recin llegados a PL/SQL saquen el mximo provecho de este len
guaje, Oracle Magazine me ha pedido que escriba una serie de artculos para princi
piantes, de los cuales ste es el primero. Si usted es un desarrollador experiment
ado en PL/SQL, tambin puede encontrar en estos artculos un repaso prctico sobre sus
fundamentos.
Para esta serie de artculos, voy a suponer que a pesar de ser nuevos en PL/SQL, m
is lectores han tenido alguna experiencia en programacin y estn familiarizados con
SQL. Mi enfoque general, adems, estar en conseguir desarrolladores productivos en
PL/SQL lo ms rpido posible.
Qu es PL/SQL?
Para contestar esta pregunta, es importante recordar que en cada sitio Web que v
isitamos, cada aplicacin que se ejecuta es construida sobre un stack (una pila) d
e tecnologas de software. En la parte superior de la pila est la capa de presentac
in, las pantallas o dispositivos interactivos con los que el usuario interacta dir
ectamente (hoy en da los lenguajes ms populares para las capas de presentacin son J
ava y .NET). En la parte inferior de la pila est el lenguaje de mquina que se comu
nica con el hardware.
En algn lugar en medio de la pila de tecnologa se encuentra la base de datos, el s
oftware que nos permite almacenar y manipular grandes volmenes de datos complejos
. La tecnologa de bases de datos relacionales, construida en torno a SQL, es la t
ecnologa de base de datos dominante en el mundo de hoy.
SQL es un lenguaje de conjuntos muy poderoso, cuyo nico objetivo es manipular el
contenido de bases de datos relacionales. Si usted desarrolla aplicaciones basad
as en bases de datos Oracle, usted (o el cdigo de alguien que escribe en un nivel
inferior de la pila de la tecnologa) debe ejecutar sentencias SQL para recuperar

datos desde o cambiar datos en la base de datos. Sin embargo, SQL no se puede u
tilizar para implementar toda la lgica de negocios y la funcionalidad que el usua
rio final necesita en nuestras aplicaciones. Esto nos lleva a PL/SQL.
PL/SQL significa Procedural Language/Structured Query Language (una extensin de p
rogramacin estructurada sobre SQL). PL/SQL ofrece un conjunto de instrucciones cls
icos de la programacin estructurada (instruccin condicional IF, loops o iteracione
s, asignaciones), organizado dentro de bloques (lo que se explica ms adelante), q
ue complementan y amplan el alcance de SQL.
Sin duda que es posible crear aplicaciones sobre Oracle y SQL sin usar PL/SQL. S
in embargo, utilizar PL/SQL para realizar operaciones especficas de bases de dato
s, particularmente la ejecucin de sentencias SQL, ofrece varias ventajas, incluye
ndo una estrecha integracin con SQL, un mejor rendimiento a travs del trfico de red
reducido, y la portabilidad (los programas PL/SQL pueden correr en cualquier in
stancia de base de datos Oracle). Por lo tanto, el cdigo del front-end de muchas
aplicaciones ejecuta tanto sentencias SQL como bloques PL/SQL, para maximizar el
rendimiento al tiempo que mejora la capacidad de mantenimiento de las aplicacio
nes.
Construyendo bloques de programas PL/SQL
PL/SQL es un lenguaje estructurado con bloques. Un bloque PL/SQL es definido por
las palabras clave DECLARE, BEGIN, EXCEPTION, y END, que dividen el bloque en t
res secciones
1. Declarativa: sentencias que declaran variables, constantes y otros elementos
de cdigo, que despus pueden ser usados dentro del bloque
2. Ejecutable: sentencias que se ejecutan cuando se ejecuta el bloque
3. Manejo de excepciones: una seccin especialmente estructurada para atrapar y ma
nejar cualquier excepcin que se produzca durante la ejecucin de la seccin ejecutabl
e
Slo la seccin ejecutable es obligatoria. No es necesario que usted declare nada en
un bloque, ni que maneje las excepciones que se puedan lanzar.
Un bloque es en s mismo una sentencia ejecutable, por lo que se pueden anidar los
bloques unos dentro de otros.
Aqu hay algunos ejemplos:
El clsico Hola Mundo! es un bloque con una seccin ejecutable que llama al procedimien
to DBMS_OUTPUT.PUT_LINE para mostrar texto en pantalla:
BEGIN
DBMS_OUTPUT.put_line('Hola Mundo!');
END;
Las funciones y procedimientos tipos de bloques con un nombre son discutidos con m
ayor detalle ms adelante en este artculo, as como los paquetes. En pocas palabras,
sin embargo, un paquete es un contenedor de mltiples funciones y procedimientos.
Oracle extiende PL/SQL con muchos paquetes incorporados en el lenguaje.
El siguiente bloque declara una variable de tipo VARCHAR2 (un string) con un lar
go mximo de 100 bytes para contener el string Hola Mundo! . Despus, el procedimiento D
BMS_OUTPUT.PUT_LINE acepta la variable, en lugar del literal, para desplegarlo:
DECLARE
l_mensaje VARCHAR2(100) := 'Hola Mundo!';
BEGIN

DBMS_OUTPUT.put_line(l_mensaje);
END;
Note que he llamado a la variable l_mensaje. Normalmente uso el prefijo l_ para
variables locales variables definidas dentro del cdigo de un bloque y el prefijo g_
para variables globales definidas en un paquete.
El siguiente ejemplo de bloque agrega una seccin de manejo de excepciones que atr
apa cualquier excepcin (WHEN OTHERS) que pueda ser lanzada y muestra el mensaje d
e error, que es retornado por la funcin SQLERRM (provista por Oracle).
DECLARE
l_mensaje VARCHAR2(100) := 'Hola Mundo!';
BEGIN
DBMS_OUTPUT.put_line(l_mensaje);
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line(SQLERRM);
END;
El siguiente ejemplo de bloque demuestra la habilidad de PL/SQL de anidar bloque
s dentro de bloques as como el uso del operador de concatenacin (||) para unir mlti
ples strings.
DECLARE
l_mensaje VARCHAR2(100) := 'Hola';
BEGIN
DECLARE
l_mensaje2 VARCHAR2(100) := l_mensaje || ' Mundo!';
BEGIN
DBMS_OUTPUT.put_line(l_mensaje2);
END;
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line(DBMS_UTILITY.format_error_stack);
END;
Ejecutando bloques PL/SQL
Una vez que hemos escrito un bloque de cdigo PL/SQL ste se puede ejecutar. Existen
muchas herramientas para ejecutar cdigo PL/SQL. La ms bsica es SQL*Plus, una inter
faz de lnea de comandos para ejecutar sentencias SQL as como bloques PL/SQL. La Fi
gura 1 muestra un ejemplo de ejecucin del ms simple de los bloques de ejemplo de n
uestro Hola Mundo! en SQL*Plus.
Ejecutando bloques PL/SQL
Figura 1: Ejecutando Hola Mundo!

en SQL*Plus

La primera cosa que hacemos despus de conectarnos a la base mediante SQL*Plus es


habilitar la salida del servidor, por lo que las llamadas a DBMS_OUTPUT.PUT_LINE
resultarn en la visualizacin de texto en la pantalla. Luego escribimos el cdigo qu
e constituye nuestro bloque. Finalmente, ingresamos una barra (/) para decirle a
SQL*Plus que ejecute ese cdigo.
SQL*Plus entonces ejecuta el bloque y muestra el Hola Mundo! en la pantalla. SQL*Pl
us es provisto por Oracle como una especie de lnea base de entorno donde se puede
n ejecutar sentencias SQL y bloques PL/SQL. Mientras que algunos desarrolladores

siguen utilizando nicamente SQL*Plus, la mayora utiliza un entorno de desarrollo


integrado (IDE). Entre los ms populares de estos entornos de desarrollo (basado e
n encuestas informales que he tomado en mis sesiones de entrenamiento) son
Oracle SQL Developer, de Oracle
eveloper, de Allround Automations

Toad y SQL Navigator, de Quest Software

PL/SQL D

Cada herramienta ofrece, con algunas diferencias, ventanas y pasos para crear, g
uardar, y ejecutar bloques PL/SQL, as como habilitar y deshabilitar la salida del
servidor. En esta serie de artculos, voy a suponer que slo tienen acceso a SQL*Pl
us y que van a ejecutar todas las sentencias en una ventana de comandos SQL*Plus
.
Pngale nombre a los bloques!
Todos los bloques que hemos visto hasta el momento son annimos , no tienen nombres.
Si los bloques annimos fueran la nica manera de organizar el cdigo, sera muy difcil u
sar PL/SQL para crear una aplicacin grande y compleja. Por esto, PL/SQL soporta l
a definicin de bloques nombrados (named blocks), tambin conocidos como subprograma
s. Los subprogramas pueden ser procedimientos o funciones. Generalmente, un proc
edimiento se utiliza para realizar una accin y una funcin se utiliza para calcular
y devolver un valor. Voy a tratar sobre subprogramas con mucho ms detalle en un
prximo artculo de esta serie. Por ahora, vamos a asegurarnos de que se comprendan
los conceptos bsicos detrs de la creacin del subprograma.
Supongamos que necesitamos mostrar "Hola Mundo!" desde mltiples lugares en nuestra
aplicacin. Queremos evitar la repeticin de la misma lgica en todos esos lugares. P
or ejemplo, qu pasa cuando tenemos que cambiar el mensaje, tal vez para "Hola Unive
rso!"? Vamos a tener que encontrar todos los lugares en nuestro cdigo donde esta
lgica aparece.
En su lugar, vamos a crear un procedimiento denominado hola_mundo mediante la ej
ecucin de la siguiente sentencia DDL (Data Definition Language):
CREATE OR REPLACE PROCEDURE hola_mundo IS
l_mensaje VARCHAR2(100) := 'Hola Mundo!';
BEGIN
DBMS_OUTPUT.put_line(l_mensaje);
END hola_mundo;
Con esto hemos extendido PL/SQL. Adems de llamar a los programas creados por Orac
le e instalados en la base de datos (como DBMS_OUTPUT.PUT_LINE), podemos llamar
a nuestro propio subprograma dentro de un bloque PL/SQL:
BEGIN
hola_mundo;
END;
Hemos escondido todos los detalles de cmo decir hola al mundo dentro del cuerpo (
body), o implementacin, de nuestro procedimiento. Ahora podemos llamar a este pro
cedimiento hola_mundo y mostrar el mensaje deseado sin tener que escribir la lla
mada a DBMS_OUTPUT.PUT_LINE o averiguar la forma correcta de darle formato al te
xto. Podemos llamar a este procedimiento desde cualquier lugar en nuestra aplica
cin. As que si alguna vez necesitamos cambiar ese texto, lo vamos a hacer en un so
lo lugar, el nico punto de definicin de ese texto.
El procedimiento hola_mundo es muy simple. Tus procedimientos tendrn mucho ms cdigo
, y casi siempre tambin tendrn parmetros. Los parmetros pasan informacin a los subpro

gramas, cuando stos son llamados, y es lo que permite crear subprogramas ms flexib
les y genricos. Se pueden usar en muchos contextos diferentes.
He mencionado antes que algn da puede ser que desee mostrar "Hola Universo!" en lug
ar de "Hola Mundo!". Podra hacer una copia de nuestro procedimiento hola_mundo y c
ambiar el texto que se muestra:
CREATE OR REPLACE PROCEDURE hola_universo IS
l_mensaje VARCHAR2(100) := 'Hola Universo!';
BEGIN
DBMS_OUTPUT.put_line(l_mensaje);
END hola_universo;
Podramos, sin embargo, terminar con las decenas de variantes del mismo procedimient
o hola, que hara muy difcil mantener nuestra aplicacin. Un enfoque mucho mejor es a
nalizar el procedimiento e identificar qu partes se mantienen incambiadas (son es
tticas) cuando el mensaje tiene que cambiar y qu partes cambian. Luego podemos pas
ar las partes que cambian como parmetros y tener un procedimiento nico que se pued
e utilizar en diferentes circunstancias.
As que vamos a cambiar hola_mundo (y hola_universo) a un nuevo procedimiento, hol
a_lugar:
CREATE OR REPLACE PROCEDURE hola_lugar (lugar_in IN VARCHAR2) IS
l_mensaje VARCHAR2(100);
BEGIN
l_mensaje := 'Hola ' || place_in;
DBMS_OUTPUT.put_line(l_mensaje);
END hola_lugar;
Justo despus del nombre del procedimiento, aadimos entre parntesis de apertura y ci
erre, un nico parmetro. Podemos tener varios parmetros, pero cada parmetro de la mis
ma forma bsica:
nombre_de_parametro

modo_de_parametro

tipo_de_datos

En otras palabras, debemos proveer un nombre para el parmetro, el modo o forma en


que ste ser usado (IN = slo lectura), y el tipo de dato que ser pasado al subprogra
ma a travs de este parmetro.
En este caso, vamos a pasar un texto de slo lectura al procedimiento hola_lugar.
Y ahora podemos saludar a nuestro mundo y a nuestro universo como sigue:
BEGIN
hola_lugar('Mundo!');
hola_lugar('Universo!');
END;
Ms adelante en esta serie vamos a explorar el concepto de reutilizacin y la manera
de evitar la repeticin, pero debes ser capaz de ver en este ejemplo, el poder de
ocultar la lgica detrs de un bloque con nombre.
Ahora supongamos que no slo queremos mostrar nuestros mensajes "Hola". A veces te
nemos que mantener los mensajes en una tabla en la base de datos; en otras ocasi
ones, tenemos que pasar el texto de nuevo al entorno del cliente para su visuali
zacin en un navegador Web. En otras palabras, necesitamos separar la forma en que
se construy el mensaje "Hola" de la forma en que se utiliza (se visualiza, se gu
arda, se enva otro programa, etc). Podemos alcanzar este nivel deseado de flexibi

lidad moviendo el cdigo que construye el mensaje a su propia funcin:


CREATE OR REPLACE FUNCTION
hola_mensaje(lugar_in IN VARCHAR2) RETURN VARCHAR2 IS
BEGIN
RETURN 'Hola ' || place_in;
END hola_mensaje;
Este subprograma se diferencia del procedimiento original en lo siguiente:
El tipo de programa es ahora FUNCTION y no PROCEDURE.
El nombre del subprograma ahora describe los datos que se devuelven, no las acci
ones tomadas.
El cuerpo o la implementacin del subprograma contiene ahora una clusula RETURN que
construye el mensaje y lo devuelve al bloque llamador.
La clusula RETURN despus de la lista de parmetros establece el tipo de datos devuel
to por la funcin.
Teniendo el cdigo necesario para construir el mensaje dentro de la funcin hola_men
saje, podemos utilizar este mensaje de mltiples maneras. Podemos, por ejemplo, ll
amar a la funcin para obtener el mensaje y asignrselo a una variable:
DECLARE
l_mensaje VARCHAR2(100);
BEGIN
l_mensaje := hola_mensaje('Universo');
END;
Nota que llamamos a la funcin hola_mensaje como parte de una sentencia PL/SQL (en
este caso, la asignacin de un texto a una variable). La funcin hola_mensaje devue
lve un string, por lo que se puede utilizar en lugar de un string en cualquier s
entencia ejecutable.
Tambin podemos volver a nuestro procedimiento hola_lugar y reemplazar el cdigo uti
lizado para crear el string con una llamada a la funcin:
CREATE OR REPLACE PROCEDURE
hola_lugar(place_in IN VARCHAR2) IS
BEGIN
DBMS_OUTPUT.put_line(hola_mensaje(place_in));
END hola_lugar;
Tambin podemos llamar la funcin desde una sentencia SQL. En el siguiente bloque, i
nsertamos el mensaje en una tabla de la base:
BEGIN
INSERT INTO tabla_mensaje(fecha_mensaje, texto_mensaje)
VALUES (SYSDATE, hola_mensaje('Montevideo'));
END;
Aunque la lgica del mensaje hola es muy simple, demuestra el poder de asignar nombr
es a una o ms sentencias ejecutables (un algoritmo) y luego referenciar el algori
tmo simplemente especificando el nombre y los parmetros requeridos.
Los bloques PL/SQL con nombre, permiten construir aplicaciones complejas que pue
den ser comprendidas y mantenidas con relativa facilidad.
Sobre los nombres en una base Oracle
Ahora que ya se aprecia la importancia de asignar nombres a la lgica, es tiempo d

e hablar sobre las reglas para los nombres (o, para ser ms precisos, identificado
res) tanto en PL/SQL como, de forma ms general, en una base Oracle.
Estas son las reglas para construir identificadores vlidos en una base Oracle:
El largo mximo es de 30 caracteres.
El primer caracter debe ser una letra, pero cada caracter despus del primero pued
e ser una letra, un nmero (0 a 9), un signo de pesos ($), un guin bajo (_), o un n
umeral (#). Todos los siguientes son identificadores vlidos:
hola_mundo
hola$mundo
hola#mundo
pero estos son invlidos:
1hola_mundo
hola%mundo
PL/SQL es case-insensitive (no es sensitivo a maysculas y minsculas) con respecto
a los identificadores. PL/SQL trata todos los siguientes como el mismo identific
ador:
hola_mundo
Hola_Mundo
HOLA_MUNDO
Para ofrecer ms flexibilidad, Oracle permite evitar las restricciones de la segun
da y tercera regla, encerrando al identificador entre comillas dobles. Un quoted
identifier (identificador encerrado entre comillas) puede contener cualquier se
cuencia de caracteres imprimibles excluyendo las comillas dobles; las diferencia
s entre maysculas y minsculas sern adems preservadas. As, todos los siguientes identi
ficadores son vlidos y distintos:
"Abc"
"ABC"
"a b c"
Es muy raro encontrar identificadores entre comillas en cdigo PL/SQL; algunos gru
pos de desarrollo los usan para conformar con sus convenciones de nombres o porq
ue encuentran que una mezcla de maysculas y minsculas resulta ms fcil de leer.
Estas mismas reglas aplican a los nombres de los objetos de base de datos como t
ablas, vistas y procedimientos, con una regla adicional: a menos que se encierre
n entre comillas los nombres de estos objetos, Oracle los mantendr en maysculas.
As que cuando creamos un procedimiento como el que sigue:
CREATE OR REPLACE PROCEDURE hola_mundo IS
BEGIN
DBMS_OUTPUT.put_line('Hola Mundo!');
END hola_mundo;
la base de datos Oracle lo mantendr con el nombre HOLA_MUNDO.
En el bloque siguiente, llamaremos este procedimiento tres veces, y aunque el no
mbre luzca diferente cada vez, siempre se ejecutar el mismo procedimiento:
BEGIN
hola_mundo;
HOLA_MUNDO;

"HOLA_MUNDO";
END;
Por otro lado, la base Oracle no ser capaz de ejecutar el procedimiento si lo lla
mamos como sigue:
BEGIN
"hola_mundo";
END;
Esto buscar dentro de la base un procedimiento llamado hola_mundo en lugar de HOL
A_MUNDO.
Si no se quiere que los nombres de los subprogramas se mantengan en maysculas, lo
s nombres se deben encerrar entre comillas cuando se crea el subprograma:
CREATE OR REPLACE PROCEDURE "Hola_Mundo" IS
BEGIN
DBMS_OUTPUT.put_line('Hola Mundo!');
END "Hola_Mundo";
Ejecutando SQL dentro de bloques PL/SQL
PL/SQL es un lenguaje de programacin de base de datos. Casi todos los programas q
ue escribiremos en PL/SQL leern desde, o escribirn en, una base de datos Oracle ut
ilizando SQL. Aunque estas series asumen que se conoce SQL, debemos estar consci
entes de la forma en que llamamos a las sentencias desde un bloque PL/SQL.
Y
r
s
l

aqu hay algunas buenas noticias: Oracle hace que sea muy fcil escribir y ejecuta
sentencias SQL en PL/SQL. La mayor parte de las veces, simplemente escribiremo
las sentencias SQL directamente en nuestro bloque PL/SQL y despus agregaremos e
cdigo necesario para la interfaz entre las sentencias SQL y el cdigo PL/SQL.

Supongamos, por ejemplo, que tenemos una tabla llamada empleados, con una column
a clave primaria id_empleado, y una columna apellido. Podemos ver el apellido de
l empleado con ID 138, como sigue:
SELECT apellido
FROM empleados
WHERE id_empleado = 138
Ahora querramos ejecutar esta misma consulta dentro de nuestro bloque PL/SQL y de
splegar el nombre. Para hacer esto, necesitaremos copiar el apellido desde la tabl
a a una variable local, lo cual podemos hacer con la clusula INTO:
DECLARE
v_apellido empleados.apellido%TYPE;
BEGIN
SELECT apellido
INTO v_apellido
FROM empleados
WHERE id_empleado = 138;
DBMS_OUTPUT.put_line(v_apellido);
END;
Primero declaramos una variable local, y haciendo esto introducimos otra caracte
rstica elegante de PL/SQL: la capacidad de fijar el tipo de datos de nuestra vari
able en funcin del tipo de datos de una columna en una tabla (esto ser profundizad

o ms adelante en esta serie)


Despus ejecutamos una consulta contra la base, obteniendo el apellido del emplead
o y asignndolo directamente en la variable v_apellido.
Por supuesto, querremos hacer ms que ejecutar sentencias SELECT en PL/SQL, tambin
querremos insertar, modificar y eliminar datos desde PL/SQL. Aqu hay ejemplos de
cada uno de esos tipos de sentencias DML:
Eliminamos todos los empleados en el departamento 10 y mostramos cuntas tuplas fu
eron eliminadas:
DECLARE
v_id_departamento empleados.id_departamento%TYPE := 10;
BEGIN
DELETE FROM empleados
WHERE id_departamento = v_id_departamento;
DBMS_OUTPUT.put_line(SQL%ROWCOUNT);
END;
Referenciamos la variable PL/SQL directamente dentro de la sentencia DELETE. Cua
ndo el bloque se ejecuta, la variable se reemplaza con el valor actual, 10, y el
DELETE es ejecutado por el motor de SQL. SQL%ROWCOUNT es un atributo especial d
e cursor que retorna el nmero de tuplas modificadas por la ltima sentencia DML eje
cutada en nuestra sesin.
Modificar todos los empleados en el departamento 10 con un 20% de incremento sal
arial.
DECLARE
v_id_departamento empleados.id_departamento%TYPE := 10;
BEGIN
UPDATE empleados
SET salario = salario * 1.2
WHERE id_departamento = v_id_departamento;
DBMS_OUTPUT.put_line(SQL%ROWCOUNT);
END;
Insertar un nuevo empleado en la tabla.
BEGIN
INSERT INTO empleados (id_empleado
, apellido
, id_departamento
, salario)
VALUES (100
, 'Feuerstein'
, 10
, 200000);
DBMS_OUTPUT.put_line(SQL%ROWCOUNT);
END;
En este bloque, provemos los valores de las columnas como literales, en lugar de
variables, directamente dentro de la sentencia SQL.
Recursos para Desarrolladores PL/SQL

Si recin ests comenzando con PL/SQL, deberas conocer y aprovechar la multitud de re


cursos gratuitos online que existen. Aqu hay algunos de los ms populares y tiles:
La pgina de PL/SQL en OTN (Oracle Technology Network), en oracle.com/technetw
ork/database/features/plsql: un excelente punto de comienzo para explorar recurs
os de PL/SQL en el popular sitio de OTN
PL/SQL Obsession, en ToadWorld.com/SF: una coleccin de recursos de desarrollo
PL/SQL del autor, incluyendo material de entrenamiento, presentaciones, cdigo ej
emplo, estndares, videos de buenas prcticas, y ms
PL/SQL Challenge, en plsqlchallenge.com: una pregunta diaria sobre PL/SQL qu
e te ayudar a evaluar y mejorar tu conocimiento sobre PL/SQL
A continuacin: Controlando la ejecucin en el bloque
En este artculo, has aprendido cmo se enmarca PL/SQL en el amplio mundo de la base
de datos Oracle. Has aprendido tambin cmo definir bloques de cdigo PL/SQL y a nomb
rar esos bloques, de forma que el cdigo de tu aplicacin puede ser utilizado y mant
enido con ms facilidad. Finalmente, fuiste introducido en la ejecucin de sentencia
s SQL dentro de PL/SQL.
Por qu anidar bloques?
Podemos poner BEGIN antes de cualquier conjunto de una o ms sentencias ejecutable
s seguidas de un END, creando un bloque anidado con esas sentencias. Hay dos ven
tajas principales para hacer esto: (1) posponer la asignacin de memoria para vari
ables que se necesitan nicamente en el bloque anidado, y (2) limitar la propagacin
de una excepcin lanzada por una de las sentencias del bloque anidado.
Consideremos el siguiente bloque:
DECLARE
l_mensaje1 VARCHAR2(100) := 'Hola';
l_mensaje2 VARCHAR2(100) := ' Mundo!';
BEGIN
IF SYSDATE >= TO_DATE('01-JAN-2012')
THEN
l_mensaje2 := l_mensaje1 || l_mensaje2;
DBMS_OUTPUT.put_line(l_mensaje2);
ELSE
DBMS_OUTPUT.put_line(l_mensaje1);
END IF;
END;
El bloque despliega Hola Mundo! cuando la fecha de hoy (retornada por SYSDATE) es p
or lo menos el primer da de 2012; en otro caso, nicamente despliega el mensaje Hola .
Aunque este bloque se ejecute en 2011, asigna memoria para la variable l_mensaj
e2.
Si reestructuramos este bloque, la memoria para l_mensaje2 ser asignada nicamente
despus del 2011:
DECLARE
l_mensaje1 VARCHAR2(100) := 'Hola';
BEGIN
IF SYSDATE > TO_DATE('01-JAN-2011')
THEN
DECLARE
l_mensaje2 VARCHAR2(100) := ' Mundo!';
BEGIN

l_mensaje2 := l_mensaje1 || l_mensaje2;


DBMS_OUTPUT.put_line(l_mensaje2);
END;
ELSE
DBMS_OUTPUT.put_line(l_mensaje1);
END IF;
END;
De forma similar, podemos agregar una seccin de excepciones a este bloque anidado
, atrapando errores y permitiendo que el bloque exterior contine con su ejecucin:
DECLARE
l_mensaje1 VARCHAR2(100) := 'Hola';
BEGIN
DECLARE
l_mensaje2 VARCHAR2(5);
BEGIN
l_mensaje2 := ' Mundo!';
DBMS_OUTPUT.put_line(l_mensaje1 || l_mensaje2);
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line(DBMS_UTILITY.format_error_stack);
END;
DBMS_OUTPUT.put_line(l_mensaje1);
END;
En este caso, el bloque anidado lanzar una excepcin VALUE_ERROR, porque la variabl
e l_mensaje2 es muy pequea (mximo de 5 bytes) para el texto
Mundo! .La seccin de exce
pciones del bloque anidado atrapar y desplegar el error. El bloque exterior contin
uar su ejecucin.
Un posterior artculo en estas series se enfocar en cmo funciona el manejo de excepc
iones en PL/SQL.
Ms adelante en esta serie de artculos, mostrar cmo controlar el flujo de ejecucin en
nuestros bloques: lgica condicional con IF y CASE; lgica iterativa con FOR, WHILE
y LOOP; as como lanzar y manejar excepciones.

You might also like