Está en la página 1de 11

PL/SQL

1. Introduccin
2. Variables
2.1. Declaracin de variables
2.2. Asignacin de valores a variables
2.3. Atributo %TYPE
2.4. Variables BOOLEANAS
3. rdenes ejecutables PL/SQL
3.1. Comentarios PL/SQL
3.2. Funciones PL/SQL
3.3. Conversin de tipos
3.4. Operadores
4. Entrada/Salida
4.1. Entrada de datos
4.2. Salida de datos
5. Estructuras de control
5.1. IF-THEN-ELSE
5.2. LOOP
5.3. FOR
5.4. WHILE
6. Cursores
6.1. Uso de cursores
6.2. Cursores parametrizados
6.3. Bucles de cursor FOR
7. Procedimientos y Funciones PL/SQL
7.1. Procedimientos PL/SQL
7.2. Funciones PL/SQL

1. Introduccin

PL/SQL es un lenguaje de programacin estructurado. Es un lenguaje procedimental que ampla
la funcionalidad de SQL, aadiendo estructuras habituales en otros lenguajes de programacin,
entre las que se encuentran:

Variables y Tipos
Estructuras de control
Procedimientos y Funciones
Tipos de Objetos y Mtodos.

La unidad bsica en PL/SQL es el bloque. Todos los programas PL/SQL estn compuestos por
bloques que pueden estar anidados. Un bloque PL/SQL est compuesto de tres partes:

seccin declarativa (opcional). Contiene las variables, constantes ...
seccin ejecutable (obligatoria). Contiene rdenes SQL para manipular datos de la base de
datos y rdenes PL/SQL para manipular los datos del bloque
seccin de excepciones (opcional). Especifica las acciones a realizar en caso de error o
cuando se producen excepciones en la ejecucin.
La estructura general es:

[DECLARE
variables, constantes, excepciones de usuario...]
BEGIN
rdenes SQL
rdenes PL/SQL
[EXCEPTION
acciones a realizar al ocurrir un error]
END;
/

Para ejecutar un bloque PL/SQL siempre hay que colocar al final la barra /.
Se pueden crear diferentes tipos de bloques:

Bloques annimos: Se construyen de forma dinmica y se suelen ejecutar una sola vez.
Bloques nominados: Igual que los annimos pero con una etiqueta que les da nombre.
Subprogramas: Procedimientos, paquetes y funciones, almacenados en la base de datos
y que se ejecutan en mltiples ocasiones. Los subprogramas se ejecutarn mediante una
llamada.
Disparadores (Triggers): Bloques nominados que se almacenan en la base de datos y que
se ejecutan ante algn suceso.

Para poner nombre a un bloque se le pone una etiqueta antes del DECLARE encerrado por <<...>>.
Ej: Poner el nombre Mi_Bloque a un bloque PL/SQL.

<<Mi_Bloque>> DECLARE
.
BEGIN
.
END;
/

2. Variables

Las variables se definen en la seccin declarativa de los bloques PL/SQL dnde tambin pueden
inicializarse.
La asignacin de nuevos valores a las variables puede hacerse en la parte ejecutable del bloque.
Pueden utilizarse para pasar valores como argumentos a subprogramas. Estas podrn ser de tipo
IN (variable de entrada, OUT, variable de salida o INOUT, variable de entrada/salida).
Tambin podrn utilizarse para almacenar valores devueltos o requeridos por una orden SQL.
Todas las variables tienen un tipo. Los posibles tipos de una variable son:

Escalar: Almacenan un valor nico. Son los mismos que los de las columnas de las tablas
(VARCHAR2, NUMBER, DATE, CHAR, LONG, LONG_RAW,BINARY_INTEGER, LAW_INTEGER)
ms el BOOLEAN
Compuesto: Grupos de datos: tablas PL/SQL, registros...
Puntero: Designan elementos de otros programas.
LOB (Large OBjects): Almacenan gran cantidad de informacin. Las variables de tipo LOB permiten
almacenar datos no estructurados (imgenes, texto...) de hasta 4 GB de tamao.


2.1. Declaracin de variables

Sintaxis:
<identificador> [CONSTANT] <tipo_de_dato> [NOT NULL] [{:= | DEFAULT <expresin>}];
Ej:
DECLARE
fecha DATE;
dep_num NUMBER(2) NOT NULL := 10;
ciudad VARCHAR2(10) := Ciudad Real;
Km_a_milla CONSTANT NUMBER := 1.4;

Las variables declaradas como NOT NULL siempre deben ser inicializadas. La inicializacin puede
hacerse utilizando := o la palabra reservada DEFAULT. Si una variable no se inicializa contendr el
valor NULL.
Las constantes deben ser inicializadas.

2.2. Asignacin de valores a variables

Sintaxis:
<identificador> := <valor>;
Ej:
dep_num := 10;

2.3. Atributo %TYPE

El atributo %TYPE se utiliza para declarar una variable con el mismo tipo que una columna de una
tabla o que otra variable definida anteriormente.

Sintaxis:
<identificador> {<tabla>.<columna> | <nombre_variable>}%TYPE;
Ej:
var_nombre Empleados.nombre%TYPE;
balance NUMBER;
balance_minimo balance%TYPE := 10;

2.4. Variables BOOLEANAS

Las variable BOOLEANAS pueden tomar el valor TRUE, FALSE o NULL.
Las variables pueden combinarse mediante operadores lgicos (NOT, AND, OR).
Las expresiones pueden devolver valores BOOLEANOS utilizando operadores relacionales (<, <=...).

3. rdenes Ejecutables

3.1. Comentarios en PL/SQL

Pueden aadirse comentarios al cdigo. Estos comentarios pueden ser especificados con:

/*comentario que ocupa
ms de una linea */

-- comentario de una sola lnea


3.1. Funciones PL/SQL

Las funciones utilizables en SQL (LOWER, UPPER, INITCAP, CANCAT, SUBSTR, LENGTH, ROUND,
TRUNC, MOD, MONTHS_BETWEEN, ADD_MONTHS, NEXT_DAY, LAST_DAY) excepto las de
agrupamiento (ya que estas se aplican sobre una columna de una tabla).

3.2. Conversin de tipos

Existen funciones de conversin de tipos: TO_CHAR, TO_DATE, TO_NUMBER

Sintaxis:
TO_CHAR (<valor>, <formato>)
TO_DATE(<valor>, <formato>)
TO_NUMBER(<valor>, <formato>)

3.3. Operadores

Los operadores en PL/SQL son los mismos que para SQL: Aritmticos, Lgicos, Concatenacin,
Parntesis. Y adems, existe el operador exponencial (**).

4. Entrada/Salida

Los programas PL/SQL suelen realizar operaciones especficas sin interactuar con el operador. Sin
embargo, existen algunas funciones que pueden ayudar a depurar programas y a interactuar con
el usuario mostrando datos por pantalla y pidiendo datos al usuario.

4.1. Salida de datos

Para mostrar una cadena por pantalla se utiliza:

DBMS_OUTPUT.PUT_LINE(<cadena de caracteres> || variable);

Se utiliza el operador || para concatenar.

Lo primero que se debe hacer para poder ver los mensajes en pantalla es activar la opcin
SERVEROUTPUT. Para ello se escribe:

SET ServerOutput ON;

4.2. Entrada de datos

Cuando se trabaja pidiendo datos al usuario es habitual especificar la opcin SET VERIFY
OFF para evitar que el sistema muestre el valor que tena la variable antes y que confirme el
nuevo valor que toma.
Para pedir datos al usuario se utiliza una variable de substitucin, dentro del cdigo fuente del
bloque PL/SQL, si esta variable no est inicializada, se le pedir el valor al usuario.
Para ello se utiliza &variable:

Ej:
SET ServerOutput ON;
SET VERIFY OFF;
DECLARE
vv NUMBER :=&v;
BEGIN
DBMS_OUTPUT.PUT_LINE('Valor de v: '||vv);
END;
/

5. Estructuras de control

5.1. Orden IF

Su sintaxis es la siguiente:

IF <expresin1> THEN
<Secuencia_ordenes1>;
[ELSIF <expresin2> THEN
<Secuencia_ordenes2>;]
[ELSE
<Secuencia_ordenesN>;]
END IF;

Ej:
DECLARE
v_num NUMBER := &v;
BEGIN
IF v_num < 50 THEN
DBMS_OUTPUT.PUT_LINE('Valor pequeo');
ELSIF v_num < 100 THEN
DBMS_OUTPUT.PUT_LINE('Valor mediano');
ELSE
DBMS_OUTPUT.PUT_LINE('Valor grande');
END IF;
END;
/

5.2. Orden LOOP

Los bucles LOOP son bucles que se ejecutan siempre, para salir de ellos hay que indicar una
instruccin de salida dentro del bucle. Su sintaxis es:

LOOP
[EXIT WHEN <condicin>]
END LOOP;

Ej:
DECLARE
num NUMBER :=1;
BEGIN
LOOP
DBMS_OUTPUT.PUT_LINE('Valor: '|| num);
num := num +1;
EXIT WHEN num > 10;
END LOOP;
END;
/

5.3. rden FOR

Los bucles FOR se repiten un nmero determinado de veces. Su sintaxis es:

FOR <contador> IN <min>..<max> LOOP
...
END LOOP;
El bucle lo hace de un valor menor a un valor mayor.

FOR <contador> IN REVERSE <min>..<max> LOOP
...
END LOOP;

El bucle lo hace de un valor mayor a un valor menor.

Ej:
DECLARE
num NUMBER;
BEGIN
FOR num IN 1..10 LOOP
DBMS_OUTPUT.PUT_LINE('Valor: '|| num); -- Escribe los nmeros del 1 al 10
END LOOP;
END;
/

DECLARE
num NUMBER;
BEGIN
FOR num IN REVERSE 1..10 LOOP
DBMS_OUTPUT.PUT_LINE('Valor: '|| num); -- Escribe los nmeros del 10 al 1
END LOOP;
END;
/

5.4. rden WHILE

Los bucles WHILE son iguales que en otro lenguajes de programacin. Su sintaxis es:

WHILE <condicion> LOOP
...
END LOOP;

Ej:
DECLARE
num NUMBER:=1;
BEGIN
WHILE num <=10 LOOP
DBMS_OUTPUT.PUT_LINE('Valor: '|| num);
num := num + 1;
END LOOP;
END;
/
6. Cursores

Los cursores son punteros a unas zonas de memoria llamadas reas de contexto en las cuales
se almacena informacin acerca del resultado de una consulta, as como el conjunto de registros
procesados y no procesados.
Mediante este puntero (cursor), un programa PL/SQL puede controlar el rea de contexto y
manejar el conjunto de registros devueltos por una consulta.
Existen 2 tipos de cursores los implcitos y los explcitos.

6.1 Cursores Implcitos.

Los cursores implcitos se utilizan para realizar consultas SELECT que devuelven un nico registro. Su
declaracin se hace de la siguiente manera:

SELECT atributos INTO variable_cursor FROM tabla WHERE condicin;

Con cada cursor implcito 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 implcitos solo pueden devolver una nica fila. En caso de que se devuelva ms de una
fila o ninguna fila se producir una excepcin.

Ej: DECLARE
vdescripcion VARCHAR2(50);
BEGIN
SELECT descripcion INTO vdescripcion FROM paises WHERE co_pais = 'ESP';
dbms_output.put_line('La lectura del cursor es: ' || vdescripcion);
END;

Las excepciones asociadas a los cursores implcitos son:

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 implcito slo es capaz de recuperar una fila ,
esta excepcin detecta la existencia de ms de una fila.
6.2. Cursores explcitos.

Los cursores explcitos se emplean para realizar consultas SELECT que pueden devolver cero filas,
o ms de una fila. Para trabajar con un cursor explicito se necesita realizar las siguientes tareas:

1. Declaracin del cursor
2. Apertura del cursor
3. Recogida de los resultados en variables PL/SQL
4. Cierre del cursor

Para declarar un cursor se utiliza la siguiente sintaxis:

CURSOR <nombre_cursor> IS <orden_SELECT>

Para abrir un cursor se pone: OPEN <nombre_cursor>

Para recoger los datos que devuelve un cursor se utiliza la orden FETCH. Su sintaxis es:

FETCH <nombre_cursor> INTO {<lista_variables>|<registro>}

Despus de utilizar el FETCH se incrementa el puntero del conjunto activo para que apunte al
siguiente registro, de tal manera que en un bucle, cada FETCH devolver filas sucesivas del
conjunto activo.

Para cerrar un cursor se pone: CLOSE <nombre_cursor>;

Los atributos que se utilizan para saber cundo se ha terminado de recorrer el conjunto activo
son:
%NOTFOUND o %FOUND que devuelve TRUE si la ultima instruccin FETCH no devolvi
una fila o si devolvi una fila respectivamente.

Otros atributos son:

%ISOPEN nos indica si el cursor est abierto

%ROWCOUNT nos dice el nmero de registros extrados por el cursor hasta el momento.
Ej:
DECLARE
v_CODIGO AREAS.CODIGO%TYPE;
v_NOMBRE AREAS.NOMBRE%TYPE;
CURSOR c_AREAS IS
SELECT CODIGO, NOMBRE FROM AREAS ORDER BY CODIGO;
BEGIN
OPEN c_AREAS;
LOOP
FETCH c_AREAS INTO v_CODIGO, v_NOMBRE;
EXIT WHEN c_AREAS%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v_CODIGO || ' - ' ||v_NOMBRE);
END LOOP;
CLOSE c_AREAS;
END;
/

6.3. Cursores parametrizados

Permiten utilizar la orden OPEN para enviar las variables de acoplamiento de un cursor.

Ej: Aqui se crea un cursor para las reas cuyo cdigo se pasa por parmetro en la orden OPEN

DECLARE
v_CODIGO AREAS.CODIGO%TYPE;
v_NOMBRE AREAS.NOMBRE%TYPE;
CURSOR c_AREAS (v_COD AREAS.CODIGO%TYPE) IS
SELECT CODIGO, NOMBRE FROM AREAS WHERE CODIGO = v_COD;
BEGIN
OPEN c_AREAS ('ATC');
LOOP
FETCH c_AREAS INTO v_CODIGO, v_NOMBRE;
EXIT WHEN c_AREAS%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v_CODIGO || ' - ' ||v_NOMBRE);
END LOOP;
CLOSE c_AREAS;
END;
/

6.4 Bucles de cursor FOR

Cuando se utilizan bucles FOR el procesamiento es mucho ms sencillo, ya que abren, recuperan
los datos y cierran el cursor de forma implcita.

Su sintaxis es la siguiente:

FOR <variable> IN <cursor> LOOP
<codigo>
END LOOP;

Ej:
DECLARE
CURSOR C_PROFES IS
SELECT nombre_pila FROM profesores;
BEGIN
FOR VP IN C_PROFES LOOP
DBMS_OUTPUT.PUT_LINE ('Nombre: ' || VP.nombre_pila);
END LOOP ;
END ;
/

6.5 Cursores para la actualizacin de registros.

Hasta ahora se han usado los cursores para seleccionar datos, pero tambin se puede utilizar el
nombre del cursor que apunta a una fila para realizar una operacin de actualizacin de esa fila.
La declaracin es la siguiente:

Cursor nombre_cursor IS
SELECT . FOR UPDATE;

FOR UPDATE indica que las filas seccionadas por el cursor van a ser actualizadas o borradas.
Todas las filas seleccionadas, sern bloqueadas tan pronto se abra el cursor con Open, y sern
desbloquedas al terminar las actualizaciones.

Tambin hay que especificar CURRENT OF en la sentencia UPDATE/DELETE. La sintaxis quedara de la
siguiente manera:
UPDATE/DELETE ..... WHERE CURRENT OF nombre_cursor

Si la consulta del cursor hace referencia a muchas tablas, se debe utilizar:

FOR UPDATE OF <nombre_columna>

con lo que nicamente se bloquearan las filas correspondientes de la tabla que contenga la columna
especificada.
CURSOR <nombre_cursor> IS
SELECT ... FOR UPDATE OF<nombre_columna>

Ej: Actualizar la cantidad de la tabla Ventas en funcin de la siguiente condicin:

Si hay menos de 100 unidades se incrementara en 75 unidades.
Si hay menos de 500 unidades se incrementara en 50 unidades.
En los dems casos se incrementara en 25 unidades.

DECLARE
Cursor c IS
SELECT * FROM ventas FOR UPDATE;
elem ventas%Rowtype;

BEGIN
OPEN c;
FETCH c INTO elem;
While c%FOUND Loop
If (elem.cantidad < 100) then
elem.cantidad:= elem.cantidad+75;
elsif (elem.cantidad < 500) then
elem.cantidad:= elem.cantidad+50;
else elem.cantidad:= elem.cantidad+25;
end if;
UPDATE ventas SET cantidad=elem.cantidad WHERE CURRENT OF c;
FETCH c INTO elem;
End Loop;
Close c;
End;

7. Procedimientos y Funciones PL/SQL

Los procedimientos y las funciones son bloques PL/SQL con nombre que tienen un comportamiento
especial. La diferencia entre los procedimientos y las funciones es que los procedimientos realizan
una tarea sin devolver nada y las funciones realizan operaciones y devuelven el resultado de esas
operaciones.

7.1. Procedimientos PL/SQL

Un procedimiento PL/SQL es similar a los procedimientos de otros lenguajes de programacin.
Un procedimiento es un bloque PL/SQL con nombre que tiene la misma estructura que los
bloques annimos. La estructura general de un procedimiento PL/SQL es:

CREATE OR REPLACE PROCEDURE nombre (
param [IN | OUT | INOUT] <tipo> [, param *IN|OUT|INOUT+ <tipo>,+ ) {IS|AS}
[DECLARE]
BEGIN
<codigo del procedimiento>
[EXCEPTION]
END;

Cuando se crea un procedimiento, ste se compila en primer lugar y queda almacenado en la
base de datos de forma compilada. El cdigo compilado puede ser posteriormente utilizado por
cualquier bloque PL/SQL.
Para modificar un procedimiento creado se debe reemplazar por el nuevo, compilndolo de nuevo
y aadiendo las palabras clave OR REPLACE. Se puede eliminar un procedimiento mediante la orden
DROP PROCEDURE <nombre>

Ej:
CREATE OR REPLACE PROCEDURE Muestra (Cad IN Varchar(20)) AS
BEGIN
DBMS_OUTPUT.PUT_LINE (Cad);
END;
DECLARE
Mens := &Mensaje
BEGIN
Muestra(Mens);
END;

7.2. Funciones PL/SQL

Las funciones son iguales que los procedimientos pero adems devuelven un valor, por lo que la
llamada a la funcin debe realizarse dentro de una expresin.




La estructura general de una funcin es:

CREATE OR REPLACE FUNCTION nombre (
param [IN | OUT | INOUT] <tipo> *, param *IN|OUT|INOUT+ <tipo>,+ )
RETURN <expresin> {IS|AS}
[DECLARE]
BEGIN
<codigo del procedimiento>
RETURN <valor>
[EXCEPTION]
END;

La orden RETURN dentro de una funcin devuelve el valor que la funcin debe devolver, el
cual se convierte al tipo especificado en la cabecera de la funcin. Puede haber ms de una
instruccin RETURN, pero solo se ejecutar la primera que se encuentre dentro de la lgica
del programa.

Ej:
CREATE OR REPLACE FUNCTION Factorial (N IN NUMBER) RETURN NUMBER AS
BEGIN
IF N<0 THEN
Return -1;
ELSIF N=0 THEN
Return 1;
ELSE
Return N*Factorial(N-1);
END IF;
END Factorial;
DECLARE
v NUMBER := &valor;
f NUMBER;
BEGIN
f := Factorial(v);
DBMS_OUTPUT.PUT_LINE ('Factorial de ' || v || ' = '|| f);
END;
/

También podría gustarte