Sei sulla pagina 1di 21

Base de Datos I

SQL PROCEDURAL
Triggers y Stored Procedures

UNCPBA - 2007
SQL Procedural

Posibilita el uso de cdigo procedural conjuntamente con


sentencias SQL que son almacenadas dentro de la BD. El cdigo
procedural es ejecutado por el DBMS cuando es invocado
(directa o indirectamente) por el usuario de la BD.

Ventajas:
Asla partes comunes existentes en las aplicaciones,
delegndolas en el DBMS.

Desventajas:
Cada proveedor de BDs tiene su propio lenguaje procedural.
El SQL-1999 incorpor estas caractersticas,
Poco de lo definido anteriormente se ajustaba a un estndar.
SQL Procedural

Se puede utilizar SQL Procedural para definir:

Trigger: Es un procedimiento que es invocado


automticamente por el DBMS en respuesta a un
evento especifico de la BD.

Stored Procedure: Es un procedimiento que es


invocado explcitamente por el usuario.

Funcin: definida por el usuario para realizar


operaciones especficas sobre los datos, y pueden ser
invocadas desde un trigger, stored procedure o
explcitamente.
Extensin en SQL-1999

SQL-1999 ha extendido el SQL-1992 en varios aspectos, uno de


ellos el procedural.

Extensiones Procedimentales:
Sentencias compuestas (agruparlas en bloques begin end)
Declaracin de variables y constantes.
Sentencias de Flujo de control:
If-then-else (elsif)
While
For (itera sobre los elementos de una tabla resultado)
Loop y repeat
Triggers o disparadores

Puede ser visto como una regla evento-condicin-accin (ECA),


es decir, cuando ocurre un evento se evala una condicin, si
sta es verdadera se ejecuta una accin.

En SQL-1999 un trigger puede ser creado, modificado o


eliminado con las siguientes sentencias:
CREATE TRIGGER
ALTER TRIGGER
DROP TRIGGER
Triggers componentes

Los componentes de un trigger son:

Un nombre nico que identifica al trigger dentro de la base


Un evento de disparo asociado (INSERT, UPDATE o DELETE).
Un tiempo de activacin que puede ser BEFORE o AFTER de la
ejecucin del evento
Una granularidad que puede ser FOR EACH ROW o FOR EACH
STATEMENT (opcin por defecto)
Una condicin que puede ser cualquier condicin SQL vlida
Una accin que puede ser un conjunto de sentencias SQL
procedurales
Renombrar las tuplas temporarias con REFERENCING NEW AS y
REFERENCING OLD AS
Triggers caractersticas:

Caractersticas principales:
La accin puede ejecutarse antes del evento disparador, despus de l
o en vez de l.
La accin puede referirse a valores anteriores y nuevos que se
insertaron, eliminaron o actualizaron en el evento que desencaden la
accin.
Los eventos de actualizacin pueden especificar un atributo particular o
un conjunto de atributos.
Una condicin puede especificarse con una clusula WHEN, y la
accin se ejecutar slo si se dispara la regla y si se cumple la
condicin cuando ocurre el evento disparador.
El programador tiene la opcin de especificar que la accin se realice:
l una vez para cada tupla modificada

l una vez para todas las tuplas que cambian en una

operacin de la base de datos.


Triggers sintaxis:

En SQL-99 la sintaxis de un trigger es la siguiente:

CREATE [O REPLACE] TRIGGER <nombre del trigger>


BEFORE | AFTER <evento> ON <nombre-tabla> evento
[ REFERENCING OLD | NEW AS <nombre-ref>]
[ FOR EACH { ROW | STATEMENT} ]
[ WHEN < condicin > ] condicin

BEGIN
cuerpo del trigger accin
END;
Triggers (Evento-Condicin-Accin)

Evento: INSERT, DELETE O UPDATE [ OF <lista-atributos>]


Ej: AFTER DELETE ON nombre_tabla
AFTER UPDATE OF nombre_columna ON nombre_tabla
Condicin: puede ser cualquier condicin SQL vlida. Slo para
disparadores a nivel de fila
Operadores relacionales: <, <=, >, >=, =, <>
Operadores lgicos: AND, OR, NOT
OLD, NEW ( Si estn el en cuerpo del trigger se referencian
como :OLD :NEW)
Accin: pueden ser un conjunto de sentencias SQL procedurales.
Para renombrar las tuplas temporarias usar REFERENCING NEW AS
y REFERENCING OLD AS.
Triggers - comportamiento

Se disparan automticamente al producirse el evento


La accin del trigger es un procedimiento atmico (Si cualquier
sentencia del cuerpo del trigger falla, la accin completa del trigger
se deshace, incluyendo la sentencia que lo dispar).
No se pueden incluir sentencias del DDL, ni COMMINT ni
ROLLBACK
Un trigger BEFORE no debe contener sentencias SQL que alteren
datos (INSERT, UPDATE, DELETE)
Varios triggers pueden activarse ante un mismo evento.
Si la activacin de un trigger T1 dispara otro trigger T2: se
suspende la ejecucin de T1, se ejecuta el trigger anidado T2 y
luego se retoma la ejecucin de T1.
Triggers - ejemplos

CREATE TRIGGER Ejemplo-fila


AFTER DELETE ON tabla1
FOR EACH ROW
WHEN ((OLD.nombre=pepe) OR (OLD.edad > 35))
BEGIN
DELETE FROM tabla2 WHERE tabla2.cod=:OLD.cod;
END;

CREATE TRIGGER Ejemplo_sentencia


AFTER DELETE ON tabla1
REFERENCING OLD AS anterior
BEGIN
DELETE FROM tabla2 WHERE tabla2.cod=anterior.cod;
END;
Triggers ejemplo

Ejemplo en Oracle:

CREATE OR REPLACE TRIGGER ejemplo


BEFORE INSERT OR UPDATE OR DELETE ON tabla
BEGIN
IF DELETING THEN
Acciones asociadas al borrado
ELSIF INSERTING THEN
Acciones asociadas a la insercin
ELSE
Acciones asociadas a la modificacin
END IF;
END;
/
Triggers ejemplo

Para chequeos de integridad:

RAISE_APPLICATION_ERROR (nro_error, mensaje); [-20000 y -20999]

CREATE OR REPLACE TRIGGER ejemplo


BEFORE DELETE ON tabla
FOR EACH ROW
BEGIN
IF tabla.columna = valor_no_borrable THEN
RAISE_APPLICATION_ERROR(-20000,La fila no se puede borrar);
END IF;
...
END;
Triggers ejemplo

Ejemplo : chequear que el salario de los empleados se encuentre en


el rango correcto

CREATE OR REPLACE TRIGGER chequear_salario


BEFORE INSERT OR UPDATE ON empleado
FOR EACH ROW
WHEN (new.trabajo<>presidente)
DECLARE
v_salariomin INTEGER;
v_salariomax INTEGER;
BEGIN
SELECT MAX(salario), MIN(salario) FROM empleado
INTO v_salariomin, v_salariomax
FROM empleado
WHERE trabajo=:new.trabajo;
IF :new.salario < v_salariomin OR :new.salario > v_salariomax THEN
RAISE_APPLICATION_ERROR(-20001, Sueldo fuera de rango);
END IF;
END;
Triggers ejemplo

Ejemplo : registrar las modificaciones de los salarios

CREATE TRIGGER SAVE_SALARY_CHANGE


AFTER UPDATE ON EMPLOYEE FOR EACH ROW
BEGIN
IF (:old.salary <> :new.salary) THEN
INSERT INTO salary_history
(emp_no, change_date, updater_id, old_salary, percent_change)
VALUES
(:old.emp_no, 'NOW', user, :old.salary, (:new.salary - :old.salary) *
100 / :old.salary);
END
Stored Procedures en Oracle

CREATE [O REPLACE] PROCEDURE ProcedureName


[<input parameters>]
AS
[ <local variable declarations>]
BEGIN
<procedure statements>
END;
Stored Procedures en Oracle

Declaracin de Variables.

VarName Type;

CREATE PROCEDURE SHIP_ORDER( PO_NUM CHAR(8) )


AS
ord_stat CHAR(7);
cust_no INTEGER;
any_po NUMERIC(15,2);
BEGIN
.
END
Stored Procedures en Oracle

Ejemplo:

CREATE PROCEDURE ADJUST_SALARY_RANGE (


FACTOR NUMERIC(18,2) )
AS
BEGIN
UPDATE JOB
SET MIN_SALARY = MIN_SALARY * FACTOR,
MAX_SALARY = MAX_SALARY * FACTOR;
END;

Para ejecutarlo:

exec ADJUST_SALARY_RANGE(1.1);
Cursores en Oracle
Para acceder a las tuplas resultantes de consulta:
Create procedure
AS
var1 empleado.nombre%type;
var2 empleado.sueldo%type;
Juan 900
cursor c1 is Pedro 920
select nombre, sueldo from empleado order by sueldo;
begin Federico 1200
open c1;
Viviana 1400
fetch c1 into var1,var2;
var2 = var2 + 100; Fernando 1800
insert into registro ( sysdate, var1, var2 ); Mariano 1900
fetch c1 into var1,var2;
fetch c1 into var1,var2;
. .
fetch c1 into var1,var2;
var2 = var2 * 1.2;
insert into registro ( sysdate, var1, var2 );

close c1;
end;
Cursores en Oracle
Cursores en conjunto con LOOP:
Create procedure ..
AS
var1 empleado.nombre%type;
var2 empleado.sueldo%type;
cursor c1 is
select nombre, sueldo from empleado;
begin
open c1;

if c1%isopen then
loop
fetch c1 into var1,var2;
exit when c1%notfound;
var2 = var2 * 1.15;
insert into registro ( sysdate, var1, var2 );
end loop;
end if;

close c1;
end;
Cursores en Oracle

Otra forma de usarlos:

Create procedure
AS
var1 empleado%rowtype;
begin
for var1 in (select * from empleado)
loop
insert into registro (sysdate, var1.sueldo * 1.5 );
end loop;
end;

Potrebbero piacerti anche