Post on 14-Oct-2018
Base de Datos IBase de Datos I
SQL PROCEDURAL Triggers y Stored Procedures
Ing. Gustavo A. Correa Reina – UNCPBA – 2008
PosibilitaPosibilita elel usouso dede códigocódigo proceduralprocedural conjuntamenteconjuntamente conconsentenciassentencias SQLSQL queque sonson almacenadasalmacenadas dentrodentro dede lala BDBD.. ElEl códigocódigoproceduralprocedural eses ejecutadoejecutado porpor elel DBMSDBMS cuandocuando eses invocadoinvocado(directa(directa oo indirectamente)indirectamente) porpor elel usuariousuario dede lala BDBD..
SQL ProceduralSQL Procedural
Ventajas:Ventajas:Aísla partes comunes existentes en las aplicaciones, delegándolas en el DBMS.
Desventajas:Desventajas:Cada proveedor de BD tiene su propio lenguaje procedural. El SQL-1999 incorporó estas características, Poco de lo definido anteriormente se ajustaba a un estándar.
Se puede utilizar SQL Procedural para definir:Se puede utilizar SQL Procedural para definir:
TriggerTrigger: Es un procedimiento que es invocado : Es un procedimiento que es invocado automáticamente por el DBMS en respuesta a un automáticamente por el DBMS en respuesta a un evento especifico de la BD. evento especifico de la BD.
SQL ProceduralSQL Procedural
StoredStored ProcedureProcedure: Es un procedimiento que es : Es un procedimiento que es invocado explícitamente por el usuario.invocado explícitamente por el usuario.
Función: definida por el usuario para realizar Función: definida por el usuario para realizar operaciones específicas sobre los datos, y pueden ser operaciones específicas sobre los datos, y pueden ser invocadas desde un invocadas desde un triggertrigger, , storedstored procedureprocedure o o explícitamente. explícitamente.
Extensiones Procedimentales:
Sentencias compuestas (agruparlas en bloques begin end)
Extensión en SQLExtensión en SQL--19991999
SQLSQL--1999 ha extendido el SQL1999 ha extendido el SQL--1992 en varios aspectos, uno de 1992 en varios aspectos, uno de ellos el procedural. ellos el procedural.
Sentencias compuestas (agruparlas en bloques begin end)
Declaración de variables y constantes.
Sentencias de Flujo de control:
If-then-else (elsif)WhileFor (itera sobre los elementos de una tabla resultado)Loop y repeat
• PL-SQL
• Oracle
• Transact-SQL
• SQL Server
Extensión en SQLExtensión en SQL--19991999
Distintos de tipos de códigos Distintos de tipos de códigos ProceduralesProcedurales. .
• SQL Server
• Sybase
•Java
• Oracle
• DB2
•.net
• SQL Server
• Oracle
Puede ser visto como una regla eventoPuede ser visto como una regla evento--condicióncondición--acción (ECA), acción (ECA), es decir, “cuando ocurre un evento se evalúa una condición, si es decir, “cuando ocurre un evento se evalúa una condición, si ésta es verdadera se ejecuta una acción”. ésta es verdadera se ejecuta una acción”.
TriggersTriggers o disparadoreso disparadores
En SQLEn SQL--1999 un 1999 un triggertrigger puede ser creado, modificado o puede ser creado, modificado o eliminado con las siguientes sentencias:eliminado con las siguientes sentencias:
CREATE TRIGGER
ALTER TRIGGER
DROP TRIGGER
Los componentes de un Los componentes de un triggertrigger son:son:
Un nombre único que identifica al trigger dentro de la base
Un evento de disparo asociado (INSERT, UPDATE o DELETE).
Un tiempo de activación que puede ser BEFORE o AFTER de la
Triggers Triggers –– componentescomponentes
Un tiempo de activación que puede ser BEFORE o AFTER de la ejecución del evento
En Oracle, granularidad que puede ser FOR EACH ROW o FOR EACH STATEMENT (opción por defecto)
Una condición que puede ser cualquier condición SQL válida
Una acción que puede ser un conjunto de sentencias SQL procedurales
Renombrar las tuplas temporarias con REFERENCING NEW AS y REFERENCING OLD AS
Características principales:Características principales:La acción puede ejecutarse antes (BEFORE) del evento disparador,
después de él (AFTER) o en vez de él ( INSTEAD OF, leer documen-tación del DBMS ).
La acción puede referirse a valores anteriores y nuevos que seinsertaron, eliminaron o actualizaron en el evento que desencadenó laacción.
Triggers Triggers –– características:características:
acción.
Los eventos de actualización pueden especificar un atributo particular oun conjunto de atributos ( Depende del DBMS ).
Una condición puede especificarse con una cláusula WHEN, y laacción se ejecutará sólo si se dispara la regla y si se cumple lacondición cuando ocurre el evento disparador.
El programador tiene la opción de especificar que la acción se realice (dependiendo del DBMS):
una vez para cada tupla modificada. una vez para todas las tuplas que cambian en una operación de la base de datos.
TriggersTriggers –– forfor eacheach rowrow –– forfor eacheach statementstatement
DNI Nombre Cuota
1 Juan 133
2 Gustavo 222
3 Pedro 452
4 Mariana 164
5 Silvina 223
update cliente set cuota = cuota * 1.2
where dni > 2;
Cantidad de tuplas Afectadas ?5 Silvina 223
Un trigger for each row, se ejecuta 3 veces, una por cada tupla.
Un trigger for each statement, se ejecuta 1 vez.
En SQLEn SQL--99 la sintaxis de un trigger es la siguiente: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>]
Triggers Triggers –– sintaxis:sintaxis:
[ REFERENCING OLD | NEW AS <nombre-ref>]
[ FOR EACH { ROW | STATEMENT} ]
[ WHEN < condición > ] condición
BEGINcuerpo del trigger acción
END;
Evento: INSERT, DELETE O UPDATE [ OF <lista-atributos>]
Ej: AFTER DELETE ON nombre_tablaAFTER UPDATE OF nombre_columna ON nombre_tabla
Condición: puede ser cualquier condición SQL válida. Sólo para disparadores a nivel de fila
Triggers (EventoTriggers (Evento--CondiciónCondición--Acción)Acción)
Operadores relacionales: <, <=, >, >=, =, <>Operadores lógicos: AND, OR, NOT
OLD, NEW ( Si están el en cuerpo del trigger se referencian como :OLD ó :NEW)
Acción: pueden ser un conjunto de sentencias SQL procedurales.
Para renombrar las tuplas temporarias usar REFERENCING NEW AS y REFERENCING OLD AS.
Se disparan automáticamente al producirse el evento
La acción del trigger es un procedimiento atómico (Si cualquiersentencia del cuerpo del trigger falla, la acción completa del trigger se deshace, incluyendo la sentencia que lo disparó).
No se pueden incluir sentencias del DDL, ni COMMINT ni ROLLBACK.
Triggers Triggers -- comportamientocomportamiento
ROLLBACK.
Un trigger BEFORE no debe contener sentencias SQL que alterendatos (INSERT, UPDATE, DELETE)
Varios triggers pueden activarse ante un mismo evento.
Hay bases en donde se puede especificar el orden.
Si la activación de un trigger T1 dispara otro trigger T2: se suspende la ejecución de T1, se ejecuta el trigger anidado T2 y luego se retoma la ejecución de T1.
CREATE TRIGGER Ejemplo-filaAFTER DELETE ON tabla1FOR EACH ROWWHEN ((OLD.nombre=’pepe’) OR (OLD.edad > 35))BEGIN
DELETE FROM tabla2 WHERE tabla2.cod=:OLD.cod;END;
Triggers Triggers -- ejemplosejemplos
END;
CREATE TRIGGER Ejemplo_sentenciaAFTER DELETE ON tabla1REFERENCING OLD AS anteriorBEGIN
DELETE FROM tabla2 WHERE tabla2.cod=anterior.cod;END;
Ejemplo en Oracle: Ejemplo en Oracle:
CREATE OR REPLACE TRIGGER ejemploBEFORE INSERT OR UPDATE OR DELETE ON tablaBEGIN
IF DELETING THEN
Triggers Triggers –– ejemploejemplo
IF DELETING THENAcciones asociadas al borrado
ELSIF INSERTING THENAcciones asociadas a la inserción
ELSEAcciones asociadas a la modificación
END IF;
END;/
RAISE_APPLICATION_ERROR (nro_error, mensaje); [-20000 y -20999]
CREATE OR REPLACE TRIGGER ejemplo
Triggers Triggers –– ejemploejemplo
Para chequeos de integridad: Para chequeos de integridad:
CREATE OR REPLACE TRIGGER ejemploBEFORE DELETE ON tablaFOR EACH ROWBEGIN
IF tabla.columna = valor_no_borrable THENRAISE_APPLICATION_ERROR(-20000,‘La fila no se puede borrar’);
END IF;...END;
CREATE OR REPLACE TRIGGER chequear_salarioCREATE OR REPLACE TRIGGER chequear_salarioBEFORE INSERT OR UPDATE ON empleadoBEFORE INSERT OR UPDATE ON empleadoFOR EACH ROWFOR EACH ROWWHEN (new.trabajo<>’presidente’)WHEN (new.trabajo<>’presidente’)DECLAREDECLARE
Triggers Triggers –– ejemploejemplo
Ejemplo : “chequear que el salario de los empleados se encuentre en Ejemplo : “chequear que el salario de los empleados se encuentre en el rango correcto”el rango correcto”
DECLAREDECLAREv_salariomin INTEGER;v_salariomin INTEGER;v_salariomax INTEGER;v_salariomax INTEGER;
BEGINBEGINSELECT MAX(salario), MIN(salario) FROM empleadoSELECT MAX(salario), MIN(salario) FROM empleadoINTO v_salariomin, v_salariomaxINTO v_salariomin, v_salariomax
FROM empleadoFROM empleadoWHERE trabajo=:new.trabajo;WHERE trabajo=:new.trabajo;IF :new.salario < v_salariomin OR :new.salario > v_salariomax THENIF :new.salario < v_salariomin OR :new.salario > v_salariomax THEN
RAISE_APPLICATION_ERROR(RAISE_APPLICATION_ERROR(--20001, ‘Sueldo fuera de rango’);20001, ‘Sueldo fuera de rango’);END IF;END IF;
END;END;
Ejemplo : “registrar las modificaciones de los salarios”Ejemplo : “registrar las modificaciones de los salarios”
CREATE TRIGGER SAVE_SALARY_CHANGECREATE TRIGGER SAVE_SALARY_CHANGE
AFTER UPDATE ON EMPLOYEE FOR EACH ROWAFTER UPDATE ON EMPLOYEE FOR EACH ROW
BEGINBEGIN
IF (:old.salary <> :new.salary) THENIF (:old.salary <> :new.salary) THEN
Triggers Triggers –– ejemploejemplo
IF (:old.salary <> :new.salary) THENIF (:old.salary <> :new.salary) THEN
INSERT INTO salary_historyINSERT INTO salary_history
(emp_no, change_date, updater_id, old_salary, percent_change)(emp_no, change_date, updater_id, old_salary, percent_change)
VALUES VALUES
(:old.emp_no, 'NOW', user, :old.salary, (:new.salary (:old.emp_no, 'NOW', user, :old.salary, (:new.salary -- :old.salary) * :old.salary) * 100 / :old.salary);100 / :old.salary);
ENDEND
CREATE [O REPLACE] PROCEDURE ProcedureName [<input parameters>]
AS
Stored Procedures en OracleStored Procedures en Oracle
[ <local variable declarations>]BEGIN <procedure statements>
END;
Declaración de Variables.Declaración de Variables.
VarName Type;
CREATE PROCEDURE SHIP_ORDER( PO_NUM CHAR(8) ) AS
Stored Procedures en OracleStored Procedures en Oracle
AS ord_stat CHAR(7); cust_no INTEGER; any_po NUMERIC(15,2);
BEGIN ….
END
Ejemplo:Ejemplo:
CREATE PROCEDURE ADJUST_SALARY_RANGE (FACTOR NUMERIC(18,2) )
ASBEGINUPDATE JOB
Stored Procedures en OracleStored Procedures en Oracle
UPDATE JOB SET MIN_SALARY = MIN_SALARY * FACTOR,
MAX_SALARY = MAX_SALARY * FACTOR;END;
Para ejecutarlo:
exec ADJUST_SALARY_RANGE(1.1);
Create procedure …AS
var1 empleado.nombre%type;var2 empleado.sueldo%type;cursor c1 is
select nombre, sueldo from empleado order by sueldo;begin
open c1;
Juan 900
Pedro 920
Federico 1200
Cursores en OracleCursores en Oracle
Para acceder a las tuplas resultantes de consulta:Para acceder a las tuplas resultantes de consulta:
open c1;
fetch c1 into var1,var2;var2 = var2 + 100;insert into registro ( sysdate, var1, var2 );
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;
Viviana 1400
Fernando 1800
Mariano 1900
…. ….
Cursores en conjunto con LOOP: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
Cursores en OracleCursores en Oracle
beginopen c1;
if c1%isopen thenloop
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;