Está en la página 1de 7

c  


c  
c 

Nos encontramos ante un gestor que va incorporado en Oracle para solventar las grandes limitaciones que
teníamos con los editores SQL, en cuanto al control de las secuencias de ejecución de instrucciones, el
uso de variables, la gestión de posibles errores, etc.

Este lenguaje está basado en ADA, por lo que incluye todas las características de los lenguajes de tercera
generación. Esto nos permite manejar las variables, tener una estructura modular (procedimientos y
funciones) y controlar las excepciones. Además incorpora un completo soporte para la programación
orientada a objetos (POO).

Los programas creados con PL/SQL los podemos almacenar en nuestra base de datos como cualquier otro
objeto quedando disponibles para los usuarios. El uso del lenguaje PL/SQL es imprescindible para
construir disparadores de bases de datos (triggers).

PL/SQL está incluido en el servidor y en algunas herramientas de cliente. Soporta todos los comandos de
consulta y manipulación de datos, aportando al lenguaje SQL las estructuras de control y otros elementos
propios de los lenguajes de programación de 3º generación.

La unidad de trabajo en PL/SQL es el bloque, constituido por un conjunto de declaraciones, instrucciones


y mecanismos de gestión de errores y excepciones.

 

Con PL/SQL se pueden construir distintos tipos de programas: procedimientos, funciones y bloques
anónimos, paquetes, etc. Todos ellos tienen en común una estructura básica denominada bloque.

Un bloque tiene 3 zonas:

 donde se declaran objectos locales. Suele ir precedida por la cláusula declare (o
is o as en los procedimientos y funciones).          !  
"#$%  es una zona opcional precedida por la cláusula EXCEPTION, donde se
gestionan las excepciones. El formato genérico de un bloque es el siguiente:

[ DECLARE
<declaraciones>]
BEGIN
<instrucciones>
[EXCEPTION
<gestión de excepciones>]
END;

Las únicas cláusulas obligatorias son BEGIN y END

Antes de hacer ningún bloque tenemos que ejecutar el siguiente comando en nuestra ventana de Sql
*PLUS

set serveroutput on;

Aunque ahora no entendáis mucho os dejo un ejemplo de un bloque para que os vayáis familiarizando con
la sintaxis.

DECLARE
v_num_empleados number(2);
BEGIN
insert into depart values(99,'provisional',null);
update emple set dept_no=99 where dept_no=20;
v_num_empleados:=SQL%ROWCOUNT;
delete from depart where dept_no=20
DBMS_OUTPUT.PUT_LINE (v_num_empleados || 'Empleados cambiados a provisional');

Ya en próximos artículos nos meteremos de lleno en la construcción de bloque y en entender las lineas
arriba escritas.

ï c 

Este lenguaje suele tener unos tipos de datos compatibles con SQL para las columnas de las tablas, pero
además puede tener otros tipos de datos propios.

Para declarar los datos en un bloque tenemos que utilizar una sintaxis como esta:

DECLARE
nombre_variable Tipo dato;
BEGIN
...

Un ejemplo seria este:

DECLARE
precio NUMBER(8,2);
suma NUMBER(2) DEFAULT 0;
prenda CHAR(20) NOT NULL :='Camiseta';
descripción VARCHAR2(15);
BEGIN
....

Una de las ventajas de PL/SQL es que nos permite declarar una variable del mismo tipo que otra variable
o que una columna de una tabla. Esto lo hacemos con el atributo %TYPE.

DECLARE
nombre emple.nombre%TYPE;

Otra ventaja es que nos permite guardar el contenido de una fila entera de una tabla en una variable. Esto
lo hacemos con el atributo %ROWTYPE

DECLARE
mifila emple%ROWTYPE;

Con esto ya podemos trabajar con variables dentro de nuestro bloque. Ahora tenemos que ver las
estructuras de control que podemos manejar dentro de nuestros bloques.

"  

Las estructuras de control son básicamente las mismas que podemos utilizar en cualquier lenguaje de
programación.

La vamos a dividir en estructuras de control alternativas (IF) y estructuras de control repetitivas (WHILE,
FOR, LOOP)
La estructura del IF seria la siguiente:

IF <condición> THEN
instrucciones
ELSEIF <condición> THEN
instrucciones
....
ELSE
instrucciones
END IF;

La estructura del WHILE seria la siguiente:

WHILE <condición> LOOP


instrucciones
END LOOP;

La estructura del FOR se escribiría así:

FOR <variable> IN <mínimo> <máximo> LOOP


instrucciones
END LOOP

Si queremos que nos vaya contando al revés, es decir de 5 hasta 0 por ejemplo, la sintaxis seria la
siguiente:

FOR <variable> IN REVERSE


<final>.......<inicio> LOOP
instrucciones
.....
END LOOP;

Y la estructura del LOOP seria de esta forma:

LOOP
instrucciones
....
EXIT WHEN <condición>
instrucciones
...
END LOOP;

4 

Es importante saber que en nuestros bloques PL/SQL es bastante práctico el uso de cursores.
En este lenguaje el resultado de una consulta no va directamente al terminal del usuario, sino que se
guarda en un área de memoria a la que se accede mediante los nombrados cursores. Para realizar una
consulta en PL/SQL tenemos que guardar el resultado en cursores. Esto es muy sencillo y basta con meter
un INTO en las consultas. Un ejemplo seria este:

select <columna/s> INTO <variable/s> from <tabla> [where]

select count(*) INTO vnum from ventas;

La variable que sigue al INTO recibe el valor de la columna. Por este motivo es importante que el tipo de
dato de la variable coincida con el tipo de dato de la columna.
_

Este lenguaje dispone de los mismo tipos de datos que podemos encontrar en SQL, pero además se han
incorporado algunos nuevos:

aÊ char(n): almacena una cantidad fija de caracteres


aÊ varchar2(n): almacena cadenas de caracteres de longitudes variables
aÊ long(n): almacena cadenas de longitud variable
aÊ number(p,e): almacena numero de precisión p y escala e
aÊ boolean: almacena valores lógicos, true, false o NULL
aÊ date: almacena fechas completas, incluida la hora
aÊ raw(n): almacena datos binarios de longitud fija
aÊ long raw : almacena datos binarios de longitud variable
aÊ rowid: almacena identificadores de direcciones de fila
aÊ etc.

Además es importante señalar que el programador puede definir sus propios tipos de datos a partir de los
ya definidos.

$

Se utilizan para nombrar los objetos que intervienen en los programas PL/SQL como son las variables,
constantes, cursores, excepciones, procedimientos, etc.

Pueden tener como máximo 30 caracteres empezando siempre por una letra, que puede ir seguida por
otras letras, numeros, $, # ó _. Es importante destacar que PL/SQL no diferencia entre mayúsculas y
minúsculas. También debemos señalar que no pueden contener espacios ni signos de puntuación.

&

Como doy por sentado que todos sabemos lo que son las variables, pasaremos directamente a comentar
como se declara una variable en PL/SQL.

<nombreVariable> <tipo> [NOT NULL] [{:= | DEFAULT } <valor>]

No podemos indicar una lista de variables del mismo tipo y luego declarar el tipo, tenemos que hacerlo
una a una.

Uno ejemplo de declaración de variables seria el siguiente:

DECLARE
importe NUMBER (8,2);
contador NUMBER(2'0);
nombre char(5) NOT NULL :="Sara";
...

 '_
"'()*_
"

%TYPE: declara una variable del mismo tipo que otra, o que una columna de una tabla
%ROWTYPE : crea una variable registro cuyos campos se corresponden con las columnas de una tabla o
vista.
Por ejemplo si tenemos una variable definida previamente llamada cantidad podemos definir otra de la
siguiente forma:

total cantidad%TYPE;

De esta forma la variable total tendrá las mismas características que la variable cantidad.
Otro ejemplo seria declarar una variable que fuera del mismo tipo que la columna nombre de la tabla
profesor.

nombre_alta nombre%ROWTYPE;

ö++

La variable será local para el bloque en el que ha sido declarada y global para los bloque hijos de éste,
mientras que las variables declaradas en los bloque hijos no son globales a los bloques padre.

4

Cómo en la mayoría de los lenguajes, en este también podemos declaras constantes, de la siguiente forma:

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

)

Asignación :=
AND
Lógicos OR
NOT
Concatenación ||
Is null
=
!=
<>
<
>
Comparación
<=
>=
between...and
like
in
y sus correspondientes negaciones
Aritméticos + - * / **

, 

En PL/SQL tenemos las mismas funciones predefinidas que en SQL (AVG, MIN, MAX, COUNT, SUM,
etc), pero tenemos que tener dos cosas muy claras a la hora de utilizarlas y son:

1.Ê La función no modifica el valor de las variables o expresiones que se pasan como argumentos,
sino que devuelve un valor a partir de dicho argumento.
2.Ê Si a una función se le pasa un valor nulo en la llamada, posiblemente devolverá un valor nulo.

" 
Podemos utilizar etiquetas para poder irnos a cualquier parte del programa utilizando la sentencia GOTO
siempre y cuando se cumplan las siguientes reglas:
No pueden haber etiquetas con los mismos nombres en un mismo programa.
La etiqueta debe preceder a un bloque o a un conjunto de ordenes ejecutables
la etiqueta no puede estar dentro de estructuras de control (IF, LOOP)

 
c 

Los procedimientos y funciones quedan almacenados en la base de datos a diferencia de los bloques
anónimos que se almacenaban en el buffer.
% Al quedar los bloques anónimos almacenados en el buffer, a no ser que se guardasen en ficheros, se
perderían al limpiar el buffer, cosa que no ocurre con los procedimientos y funciones, que se almacenan
en la propia base de datos.

Otra cosa que nos diferencia los bloques anónimos de los procedimientos o funciones es que en los
procedimientos o funciones no se pueden utilizar variables de sustitución.

-4("._")(("
.4"/0 

Pasamos a escribir un procedimiento que nos muestre los datos de un usuario:

CREATE OR REPLACE PROCEDURE ver_usuario(nomusu VARCHAR2)


IS
NIFusu VARCHAR2(10);
Domusu VARCHAR2(10);
BEGIN
select nif, domicilio into NIFusu,Domusu from usuario where nombre=nomusu;
DBMS_OUTPUT.PUT_LINE('Nombre:'||nomusu|| 'NIF:' ||NIFusu|| 'Domicilio' ||Domusu);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('No hemos encontrado al usuario || nomusu);
END;
/

Si el compilador detecta errores nos saldrá un mensaje como este: ³Procedimiento creado con errores de
compilación´. Para ver estos errores tenemos la orden SHOW ERRORS.

Al tener almacenado el procedimiento en la base de datos, este puede ser llamado por cualquier usuario
que tenga los permisos oportunos. Para invocar un procedimiento utilizamos la orden EXECUTE

Para invocar al procedimiento que hemos creado antes tendríamos que ejecutar la siguiente orden:

EXECUTE ver_usuario('Luis');
Pero también podemos invocarlo desde un bloque PL/SQL de ls siguiente forma:
BEGIN
ver_usuario('Luis');
END;
.
Como en cualquier lenguaje, podemos agregar comentarios a nuestros procedimientos de la
siguiente forma:
- - para comentar en una sola linea
/* <comentario>*/ para varias lineas.

4_
Si un evento trigger ocurre, el administrador de triggers (llamado Ejecutor) inicializa la estructura global
TriggerData *CurrentTriggerData (descrita más abajo) y llama a la función trigger para procesar el
evento.
La función trigger debe ser creada antes que el trigger, y debe hacerse como una función sin argumentos,
y códigos de retorno opacos.
La sintaxis para la creación de triggers es la siguiente:
El nombre del trigger se usará si se desea eliminar el trigger. Se usa como argumento del co mando
DROP TRIGGER.
La palabra siguiente determina si la función debe ser llamada antes (BEFORE) o después (AFTER)
del evento.
El siguiente elemento del comando determina en que evento/s será llamada la función. Es posible
especificar múltiples eventos utilizado el operador OR.
El nombre de la relación (relation name) determinará la tabla afectada por el evento.
La instrucción FOR EACH determina si el trigger se ejecutará para cada fila afectada o bien antes (o
después) de que la secuencia se haya completado.
El nombre del procedimiento (procedure name) es la función C llamada.
Los argumentos son pasados a la función en la estructura CurrentTriggerData. El propósito de pasar
los argumentos a la función es permitir a triggers diferentes con requisitos similares llamar a la misma
función.
Además, la función puede ser utilizada para disparar distintas relaciones (estas funciones son
llamadas "general trigger funcions").
Como ejemplo de utilización de lo descrito, se puede hacer una función general que toma como
argumentos dos nombres de campo e inserta el nombre del usuario y la fecha (timestamp) actuales en
ellos. Esto permite, por ejemplo, utilizar los triggers en los eventos INSERT para realizar un seguimiento
automático de la creación de registros en una tabla de transacciones. Se podría utilizar también para
registrar actualizaciones si es utilizado en un evento UPDATE.
Las funciones trigger retornan un área de tuplas (HeapTuple) al ejecutor. Esto es ignorado para trigger
lanzados tras (AFTER) una operación INSERT, DELETE o UPDATE, pero permite lo siguiente a los
triggers BEFORE: - retornar NULL e ignorar la operación para la tupla actual (y de este modo la tupla no
será insertada/actualizada/borrada); - devolver un puntero a otra tupla (solo en eventos INSERT y
UPDATE) que serán insertados (como la nueva versión de la tupla actualizada en caso de UPDATE) en
lugar de la tupla original.

4   
      
ë 

   ëë  
ë 
   !

"# $%

También podría gustarte