PL/SQL
Es un lenguaje procedimental creado por Oracle, el cual utiliza como unidad de
trabajo
los BLOQUES, los cuales se almacenan en la BD como un objeto m�s.
Posee caracterisiticas de los lenguajes de 3ra generacion y OO.
Brinda la posibilidad de utilizar estructuras de control b�sicas alternativas y
Repetitivas. No poseen
ordenes para la E/S o interacci�n con el usuario.
Posee estructura modular.
PL/SQL trabaja de forma "interpretada", lo que quiere decir que un codigo
almacenado debe de ser
traducido a un codigo ejecutable. Se realiza cada vez que se ejecuta un
procedimiento.
Antes de almacenarce, todos los programas PL/SQL pasan por un analizador sintactico
y lexicogr�fico.
BLOQUES
Estructura:
Declare
[...] -- Contiene variables,ctes, cursores, y excep def para los us
Begin
[...] -- Sentencias SQL para manipular los datos y sentencias PL/SQL
para manipular datos en bloque (OBLIGATORIA)
Exception
[...] -- Acciones a tomar en caso de errores.
End;
ejemplo
Agregar un nuevo armario y mover los equipos que est�n en el armario 03 al nuevo
armario el cu�l ser�
el n�mero 04, contar la cantidad de equipos que han cambiado de lugar y eliminar el
armario 03.
declare
num_equipos NUMBER(2);
begin
INSERT INTO armario (N_armario, Tipo)VALUES (04,'M');
UPDATE equipo SET N_armario = 04 where NN_armario = 03;
num_equipos := SQL%ROWCOUNT; --Cuenta la cantidad de filas que han sido
afectadas por la secuencia anterior a modificado
DELETE FROM armario WHERE N_armario = 03;
[Link].PUT_LINE (num_equipos || 'equipos movidos al armario 4'); -- "||"
concatena
exception
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE ( 'Error en el programa');
end;
TIPOS DE BLOQUES
Bloque an�nimo: El ejemplo anterior es un ejemplo de bloque an�nimo. No posee
nombre, se ejecuta en el servidor, pero no se
almacena. Su utilidad es escasa.
Procedimientos: Tiene un nombre y se almacena en la BD, lo cu�l permite que sea
invocado desde otro progrma, lenguaje, servidor, etc.
Estos bloques se compilan, se almacenan y se ejecutan dentro del servidor
Oracle. Puede (o no) retornar valores.
Estructura:
PROCEDURE name
IS/AS
BEGIN
--satements
[EXCEPTION]
END;
Funci�n: Es igual al procedimiento, con la diferencia que siempre retornar� un
valor con un tipo preestablecido.
Estructura:
FUNTION name
RETURN datatypes
IS/AS
BEGIN
--satements
RETURN value
[EXCEPTION]
END;
Disparadores(triggers): Est�n almacenados en la BD y se relacionan con un evento
preestablecido que har� que se ejecute en forma aut�matica,
c�mo por ejemplo alguna modificaci�n en una tabla, un evento del sistema, una
hra y fecha, etc.
CURSORES
Cursos impl�cito: Cuando se ejecuta una consulta el resultado no se muestra
directamente al usuariom sino que queda almacenada en un �rea de memoria
llamada CURSOR.
Por ejemplo:
Si queremos saber el n�mero de equiposque tenemos en el inventario:
BEGIN
SELECT COUNT(*) FROM equipo;
END;
-- Esto da error. Es necesario utilizar una variable junto con la clausula
INTO
DECLARE
total_equipos NUMBER(2);
BEGIN
SELECT COUNT(*) INTO total_equipos FROM equipo;
DBMS_OUTPUT.PUT_LINE ('Total equipos: ' || total_equipos);
END;
--El select no se mostrar� en pantalla c�mo ocurr�a normalmente en SQL, por
eso debe almacenarse en una variable (tmb llamada CURSOR) para luego
--poder mostrarla en pantalla
CONDICIONALES
If: Alternativa Simple
BEGIN
--Statements
IF [...] THEN
--Statements;
END IF;
Alternativa doble
BEGIN
--Statements
IF [...] THEN
--Statements;
ELSE
--Statements;
END IF;
Alternativa m�ltiple
BEGIN
--Statements
IF [...] THEN
--Statements;
ELSIF [...]
--Statements;
END IF;
CASE: de comprobaci�n
BEGIN
--Statements
CASE <expr>;
WHEN <valor_1>
THEN
--statements;
ELSE
--statements;
END CASE;
De B�squeda
BEGIN
--Statements
CASE
WHEN <cond_1>
THEN
--statements;
ELSE
--statements;
END CASE;
Ejercicio: Calcular la cantidad de tiempo que un usuario registra una m�quina y
asignar
estados seg�n corresponda:
Si no ha devuelto el equipo PENALIZADO
Si lleva 1 o 2 dias de reserva se pondr� DEVUELTO
Si lleva m�s de 2 dias de reserva, se pondr� PENALIZADO
CREATE OR REPLACE PROCEDURE Calcula_Periodo (usr usuario.ID_Usuario%TYPE)
AS
periodo VARCHAR (20) DEFAULT 'PENDIENTE'
v_fecha_inicio DATE;
V_fecha_fin DATE;
BEGIN
select fecha:iniciom fecha_fin
INTO v_fecha_inicio, v_fecha_inicio, v_fecha_fin
from reserva
where ID_usuario = usr;
CASE
when v_fecha_fin IS NULL THEN
periodo := 'PENDIENTE'
WHEN v_fecha_fin - v_fecha_inicio < 3 THEN
periodo := 'DEVUELTO';
ELSE
periodo := 'PENALIZADO';
END CASE;
DBMS_OUTPUT.PUT_LINE ('La reserva del usuario con id ' || usr || ' es: ' ||
periodo);
EXCEPTION
WHEN no_data_found THEN
DBMS_OUTPUT.PUT_LINE ('ESTE USUARIO NO POSEE RESERVAS ACTIVAS');
END;
ESTRUCTURAS DE CONTROL
Repetitivas
LOOP <instrucciones> EXIT <cond>
WHILE <cond> LOOP
FOR <contador> IN <valor1>..<valorN> LOOP
GOTO <etiqueta>
Ejercicio
Crear la funcion PWD para obtener una contrase�a del usuario. Esta funcion puede
ser �til para resetear
dicha contrase�a en caso de olvido. La contrase�a ser� el NNOMBRE del usuario
escrito al rev�s.
�C�mo lo har�as?
CREATE OR REPLACE FUNCTION pwd (usr usuario.id_usuario%TYPE)
RETURN VARCHAR2
AS
password VARCHAR2 (20);
v_nombre [Link] %type
BEGIN
select SUBSTR(nombre, 1, INSTR(nombre, ' '))
INTO v_nombre
FROM usuario
WHERE Id_usuario = usr;
FOR i IN REVERSE 1..LENGTH(V_NOMBRE) LOOP
password := password || SUBSTR (v_nombre,i,1);
END LOOP;
RETURN passwor;
EXCEPTION
WHEN no_data_found THEN
Return ' sin contrase�a';
END;