Disparadores en SQL (i)

8
DISPARADORES EN SQL (I) MODELOS AVANZADOS DE BASES DE DATOS

Transcript of Disparadores en SQL (i)

DISPARADORES EN SQL (I)

MODELOS AVANZADOS DE BASES DE DATOS

DISPARADORES EN SQL (I)

MODELOS AVANZADOS DE BASES DE DATOS 2 Coral Calero

Objetivo Conocer la implementación de los disparadores en SQL. Sintaxis general de un disparador CREATE [OR REPLACE] TRIGGER nombre

[temporalidad del evento] [granularidad del evento]

[WHEN condición] BEGIN

cuerpo del trigger END nombre; / CREATE [OR REPLACE] TRIGGER nombre Crea o reemplaza un disparador con el nombre especificado. [temporalidad del evento] Puede tomar dos valores: BEFORE ó AFTER que indicará si el cuerpo del disparador debe ejecutarse antes o después del evento que causa la activación del disparador. Ambos valores pueden aplicarse tanto para disparadores a nivel de fila como a nivel de orden. La opción BEFORE/AFTER debe acompañarse de la operación que causa la activación del disparador. Estas pueden ser operaciones de inserción (INSERT) Y/O borrado (DELETE) y/o modificación (UPDATE) respecto a una tabla o respecto a una columna de una tabla. Cuando se quiere especificar más operación, estas se pueden unir utilizando los operadores OR y AND. La forma general de la temporalidad del evento será, por tanto: BEFORE/AFTER INSERT/UPDATE/DELETE [OF nombre_columna] ON nombre_tabla Por ejemplo: BEFORE INSERT ON empleado BEFORE INSERT OR DELETE ON empleado BEFORE UPDATE ON salario ON empleado

DISPARADORES EN SQL (I)

MODELOS AVANZADOS DE BASES DE DATOS 3 Coral Calero

Esta última se activará para una operación como: UPDATE empleado SET salario=salario+1; Y también para: UPDATE empleado SET salario=salario; Pero no para: UPDATE empleado SET emp_cod=101; La cláusula OF nombre_columna puede utilizarse tanto a nivel de fila como a nivel de orden. [granularidad del evento] [WHEN condición] Permite distinguir si el disparador es a nivel de fila o a nivel de orden. Un disparador se define a nivel de fila cuando el cuerpo del disparador se debe aplicar fila a fila de la tabla afectada y se define a nivel de orden cuando se debe aplicar a toda la tabla a la vez. Si queremos definir el disparador a nivel de fila, la granularidad deberá especificarse con la cláusula FOR EACH ROW a la que habrá que acompañar de la condición que debe cumplir la fila para aplicar el cuerpo del disparador. Esta condición se indica en la orden SQL mediante la cláusula WHEN condición. Cuando no exista definición del granularidad del evento, significará que el disparador está definido a nivel de orden. Ejemplos:

CREATE TRIGGER nivel_fila_sin_condición AFTER DELETE OF salario ON empleado

FOR EACH ROW BEGIN ... CREATE TRIGGER nivel_fila_con_condición

AFTER DELETE OF salario ON empleado FOR EACH ROW WHEN empleado.salario >60000 BEGIN ...

DISPARADORES EN SQL (I)

MODELOS AVANZADOS DE BASES DE DATOS 4 Coral Calero

CREATE TRIGGER nivel_columna AFTER DELETE OF salario ON empleado

BEGIN ... Si se quiere hacer mención en la condición WHEN al valor de la fila a borrar, se debe hacer referencia mediante las variables NEW y OLD. Así, para el ejemplo anterior, el disparador estaría correctamente definido de la siguiente manera:

CREATE TRIGGER nivel_fila_con_condición AFTER DELETE OF salario ON empleado

FOR EACH ROW WHEN OLD.salario >60000 BEGIN ... Con OLD.nombre_columna referenciamos: • al valor que tenía la columna antes del cambio debido a una modificación

(UPDATE) • al valor de una columna antes de una operación de borrado sonbre la misma

(DELETE) • al valor NULL para operaciones de inserción (INSERT)

Con NEW.nombre_columna referenciamos: • Al valor de una nueva columna después de una operación de inserción (INSERT) • Al valor de una columna después de modificarla mediante una sentencia de

modificación (UPDATE) • Al valor NULL para una operación de borrado (DELETE) Sin embargo hay que tener en cuenta que las variable OLD y NEW sólo pueden ser utilizadas cuando el disparador se ha definido a nivel de fila. BEGIN

cuerpo del trigger END nombre; Dentro del cuerpo de un disparador podemos incluir sentencias de borrado (DELETE), inserción (INSERT) o modificación (UPDATE) pero también se puede poner cualquier otra sentencia SQL (SELECT..) e incluso un programa escrito en PL/SQL. Esta última opción se verá en la siguiente práctica. Dentro de este cuerpo también se puede hacer referencia a las variables OLD y NEW sólo que en este caso habrá que utilizarlas con : delante.

DISPARADORES EN SQL (I)

MODELOS AVANZADOS DE BASES DE DATOS 5 Coral Calero

Ejemplo: BEGIN

DELETE FROM tabla2 WHERE tabla2.cod=:OLD.cod; END Ejemplo;

Órdenes de disparadores Eliminación de un disparador DROP TRIGGER nombre; Habilitación/deshabilitación de un disparador ALTER TRIGGER nombre [ENABLE|DISABLE] Habilitación/deshabilitación de todos los disparadores de una tabla: ALTER TABLE nombretabla [ENABLE|DISABLE] ALL TRIGGERS; Ver todos los disparadores definidos por un usuario SELECT TRIGGER_NAME FROM USER_TRIGGERS Ver el cuerpo de un disparador: SELECT TRIGGER_BODY FROM USER_TRIGGERS

WHERE TRIGGER_NAME = ‘nombre_disparador’; Ver la descripción de un disparador: SELECT DESCRIPTION FROM USER_TRIGGERS

WHERE TRIGGER_NAME = ‘nombre_disparador’; Bibliografía § Owens, K.T. (1996) Building Intelligent Databases with ORACLE PL/SQL,

TRIGGERS & STORED PROCEDURES, Ed. Prentice Hall. 1996 § ORACLE Guía de aprendizaje, Ed. ORACLE Press § ORACLE, Lenguaje de programación PL/SQL, Ed. ORACLE Press § La biblia de ORACLE8, Advanced Information Systems Inc., Ed. Anaya

Multimedia. 1998. § Cannan, S.J.,(1999), The SQL Files, investigation into a database language, Array

Publications. 1999.

DISPARADORES EN SQL (I)

MODELOS AVANZADOS DE BASES DE DATOS 6 Coral Calero

EJERCICIOS 1. Supongamos que tenemos las siguientes tablas con los siguientes atributos:

cuenta: nro_cuenta (10 caracteres) y balance (numérico). El campo numero_cuenta es la clave primaria. transaccion: nro_cuenta(10 caracteres), hora_modificacion (tipo fecha), id_cliente (10 caracteres), ant_balance (numérico), act_balance (numérico). Los campos nro_cuenta y hora_modificación froman la clave primaria. Crear un disparador que consiga mantener actualizada la tabla transacción cada vez que se modifique la tabla cuenta (se cambie el atributo balance).

2. Supongamos que tenemos una tabla de distancias de diferentes rutas y que queremos

guardar estas distancias en kilómetros y en millas.

Distancias: ruta (10 caracteres), distancia_k (numérico), distancia_m (numérico). Siendo ruta la clave principal. Crear disparadores para conseguir que cuando se introduzca (o se modifique) una distancia en kilómetros, automáticamente se introduzca también en millas y viceversa. (1 Km=0.621371 millas y 1 Milla=1.609344 Km)

3. Transformar el siguiente esquema relacional haciendo desaparecer las claves ajenas mediante el uso de disparadores.

CREATE TABLE EMPLOYEE( NAMEP VARCHAR(15) NOT NULL, INIC CHAR, SURNAME VARCHAR(15) NOT NULL, NSS CHAR(9) NOT NULL, DATEN DATE, ADDRESS VARCHAR(30), SEX CHAR, SALARY DECIMAL(10,2), ND NUMBER NOT NULL, PRIMARY KEY (NSS), FOREIGN KEY (ND) REFERENCES DEPARTAMENT (NUMBERD) ON DELETE CASCADE); CREATE TABLE DEPARTAMENT( NAMED VARCHAR(15) NOT NULL, NUMBERD NUMBER NOT NULL, DATEINICGTE DATE, PRIMARY KEY (NUMBERD);

DISPARADORES EN SQL (I)

MODELOS AVANZADOS DE BASES DE DATOS 7 Coral Calero

CREATE TABLE SITE_DEPTS( NUMBERD NUMBER NOT NULL, SITED VARCHAR(15) NOT NULL, PRIMARY KEY (NUMBERD, SITED), FOREIGN KEY (NUMBERD) REFERENCES DEPARTAMENT (NUMBERD) ON DELETE CASCADE); CREATE TABLE PROJECT( NAMEPR VARCHAR(15) NOT NULL, NUMBERPR INT NOT NULL, SITEPR VARCHAR(15), NUMD INT NOT NULL, PRIMARY KEY (NUMBERP), FOREIGN KEY (NUMD) REFERENCES DEPARTAMENT (NUMBERD) ON DELETE CASCADE); CREATE TABLE WORK_IN( NSSE CHAR(9) NOT NULL, NUMP INT NOT NULL, HOURS DECIMAL(3,1) NOT NULL, PRIMARY KEY (NSSE, NUMP), FOREIGN KEY (NSSE) REFERENCES EMPLOYEE (NSS) ON DELETE CASCADE, FOREIGN KEY (NUMP) REFERENCES PROJECT (NUMBERP) ON DELETE CASCADE);

4. Considerando las siguientes dos tablas:

empleado: nss(numérico), nombre (10 caracteres), salario (numérico), num_dep (10 caracteres) departamento: num_dep (10 caracteres), nombre (10 caracteres), presupuesto (numérico)

§ Diseñar un disparador que al insertar un nuevo empleado, automáticamente

quede actualizado el presupuesto total del departamento al que el empleado pertenece, añadiéndole el salario asignado al nuevo empleado.

§ Diseñar un disparador que al modificar el salario de un empleado, automáticamente quede actualizado el presupuesto total del departamento al que el empleado pertenece, en función del nuevo salario asignado al empleado.

5. Si tenemos una serie de disparadores cuyo evento es el mismo y cuya acción es la

inserción de filas en una tabla, pero de forma que estén definidos de la siguiente manera:

1 a nivel de orden con temporalidad BEFORE 1 a nivel de orden con temporalidad AFTER 1 a nivel de fila con temporalidad BEFORE 1 a nivel de fila con temporalidad AFTER

DISPARADORES EN SQL (I)

MODELOS AVANZADOS DE BASES DE DATOS 8 Coral Calero

Determinar, mediante un ejemplo, el orden en que se irán activando dichos disparadores mostrando como va variando el contenido de la tabla en la que se inserta.

Anexo. Funciones asociadas a datos de tipo fecha Los datos de tipo fecha en realidad contienen la fecha y la hora. Esto es especialmente importante cuando se comparen dos fechas. El formato por defecto es DD-Mes-AA aunque es posible cambiarlo. Entre las funciones específicas para fechas tenemos: sysdate à Fecha y hora actual last_day à último día del mes actual add_months(d,n) à suma o resta n meses a partir de la fecha d Ejemplo: select add_months('12-MAR-99',2) from usuarios; months_between(f,s) à diferencia en meses entre la fecha f y la fecha s next_day(d,day) à Fecha del día especificado (lunes, martes, ...en inglés)de la semana siguiente a d Funciones de conversión de tipos TO_CHAR (arg) à Convierte el argumento en tipo VARCHAR(2). El argumento puede ser de tipo numérico o de tipo fecha. TO_DATE(arg) à Convierte el argumento en tipo fecha. El argumento sólo puede ser de tipo carácter.

TO_NUMBER(arg) à Convierte el argumento en tipo carácter. El argumento puede sólo puede ser de tipo carácter.