Documente Academic
Documente Profesional
Documente Cultură
BASES DE DATOS
TRIGGERS
SEGUNDO DE ASIR
Pgina 1
[BASES DE DATOS] 5 de marzo de 2012 6. --> Programe, en un fichero de texto independiente, un disparador o trigger a nivel de sentencia llamado ACTIV_SIN_5REGIONES, que acte ANTES de INSERTAR una nueva actividad. El disparador no permitir que una nueva actividad sea insertada si no existen al menos 5 regiones en la tabla de Regiones. En caso contrario, la actividad se insertar sin problemas. Utilice RAISE_APPLICATION_ERROR para generar el error.
Creamos un fichero con extensin .sql que ser el que contenga el cdigo de nuestro trigger oracle@asir-VirtualBox:~$ cd paises/ oracle@asir-VirtualBox:~/sql$ sudo gedit num6.sql
Creamos el trigger con el nombre que se nos indica, en el cual el disparador que creamos no permite que una nueva actividad sea insertada si no hay al menos 17 regiones o ms, para generar el error utilizamos RAISE_APPLICATION_ERROR CREATE OR REPLACE TRIGGER ACTIV_SIN_5REGIONES BEFORE INSERT ON actividades FOR EACH ROW DECLARE v_regiones NUMBER; BEGIN SELECT count(*) INTO v_regiones FROM regiones; IF v_regiones < 17 THEN RAISE_APPLICATION_ERROR(-17000, 'Existen menos de 17 regiones'); END IF; END ACTIV_SIN_5REGIONES; /
SEGUNDO DE ASIR
Pgina 2
Entonces intentamos insertar una actividad cualquiera y como en nuestro caso existen menos de diecisiete regiones no nos deja mostrndonos el consiguiente mensaje de error SQL> INSERT INTO actividades VALUES (9, 'Marketing', 500); INSERT INTO actividades VALUES (9, 'Marketing', 500) * ERROR at line 1: ORA-20000: Existen menos de 17 regiones ORA-06512: at "GESTOR.ACTIV_SIN_5REGIONES", line 11 ORA-04088: error during execution of trigger 'GESTOR.ACTIV_SIN_5REGIONES'
SEGUNDO DE ASIR
Pgina 3
[BASES DE DATOS] 5 de marzo de 2012 7. --> Puede el usuario AKSEN crear ese disparador a pesar de que no tiene permisos para insertar en dicha tabla? NO. En caso afirmativo, borre ese disparador de AKSEN, e instlelo como usuario GESTOR y compruebe que el disparador funciona correctamente cuando el usuario GESTOR intenta insertar una nueva actividad
El usuario AKSEN no puede crear este disparador ya que el trigger esta creado sobre la tabla actividades y este usuario tiene permisos para modificar dicha tabla, aparte, tendremos que modificar tambin, el nombre de la tabla por gestor.actividades
Si no cambiamos el trigger por la tabla correspondiente gestor.actividades no podremos ver la tabla: SQL> @'paises/num6.sql'; BEFORE INSERT ON actividades * ERROR at line 2: ORA-00942: table or view does not exist
Si cambiamos el nombre de la tabla, nos dice que no tenemos privilegios: SQL> @'paises/num6.sql'; BEFORE INSERT ON gestor.actividades * ERROR at line 2: ORA-01031: insufficient privileges
SEGUNDO DE ASIR
Pgina 4
[BASES DE DATOS] 5 de marzo de 2012 8. --> Conceda el permiso necesario para que el usuario AKSEN pueda ejecutar el disparador anterior. Qu ocurre?
Damos los permisos al usuario aksen para que pueda ejecutar el disparador SQL> grant create trigger to aksen; Grant succeeded.
Comprobamos desde el usuario AKSEN que sucede y vemos que no podemos crear la tabla diciendo que no tenemos suficientes privilegios, esto es porque solo el usuario que ha creado la tabla o el usuario administrador pueden crear el trigger sobre ella. SQL> @'paises/num6.sql'; BEFORE INSERT ON gestor.actividades * ERROR at line 2: ORA-01031: insufficient privileges
SEGUNDO DE ASIR
Pgina 5
[BASES DE DATOS] 5 de marzo de 2012 9. --> Se disparar ese trigger cuando el usuario AKSEN intente insertar algo en la tabla Actividades? NO. Observe que AKSEN no tiene permiso para insertar en esa tabla, pero el disparador es de tipo BEFORE
No se dispara, pese a ser de tipo before, por los permisos del usuario AKSEN sobre esa tabla
SQL> insert into gestor.actividades values (9, 'marketing', 500); insert into gestor.actividades values (9, 'marketing', 500) * ERROR at line 1: ORA-20000: Existen menos de 17 regiones ORA-06512: at "GESTOR.ACTIV_SIN_5REGIONES", line 11 ORA-04088: error during execution of trigger 'GESTOR.ACTIV_SIN_5REGIONES'
SEGUNDO DE ASIR
Pgina 6
[BASES DE DATOS] 5 de marzo de 2012 10. --> Otorgue permisos para insertar en la tabla Actividades al usuario AKSEN. Compruebe si el disparador anterior se ejecuta cuando AKSEN inserta en esa tabla. Es necesario otorgar permisos de ejecucin sobre el disparador? NO(DA EL MISMO RESULTADO MISMO).
Lo primero que hacemos ser conectarnos como usuario GESTOR y le damos a aksen permisos de insercin sobre actividades con el siguiente comando SQL> grant insert on actividades to aksen; Grant succeeded.
De nuevo y siguiendo con AKSEN insertamos una nueva fila, bueno mejor dicho lo intentamos, porque como vemos saltara el disparador:
SQL> insert into gestor.actividades values (9, 'marketing', 500); insert into gestor.actividades values (9, 'marketing', 500) * ERROR at line 1: ORA-20000: Existen menos de 17 regiones ORA-06512: at "AKSEN.ACTIV_SIN_5REGIONES", line 7 ORA-04088: error during execution of trigger 'AKSEN.ACTIV_SIN_5REGIONES'
SEGUNDO DE ASIR
Pgina 7
[BASES DE DATOS] 5 de marzo de 2012 11. --> El usuario GESTOR crea una tabla llamada CTRL_ACTIVIDADES con los siguientes atributos: USUARIO, FECHA y OPERACION. Modifique el disparador anterior para que se inserte una fila en esta nueva tabla, donde USUARIO es el usuario que dispara su ejecucin, FECHA es la fecha actual y OPERACION tomar el valor 'INSERT' si la operacin de insercin no es abortada por el disparador. En caso contrario, el atributo OPERACION tomar el valor siguiente: INTENTO FALLIDO'. Funciona correctamente cuando el intento es fallido? NO, SOLO POR SEPARADO.
Creamos la tabla CTRL_ACTIVIDADES con el usuario gestor y con los atributos que se nos indican usuario, fecha y operacin. CREATE TABLE CTRL_ACTIVIDADES ( usuario VARCHAR2(25), fecha DATE, operacion VARCHAR2(20));
Nos conectamos como usuario gestor y creamos la tabla SQL> connect gestor Enter password: Connected.
SQL> desc ctrl_actividades; Name ------------------------USUARIO FECHA OPERACION --------------VARCHAR2(25) DATE VARCHAR2(20) Null? Type
SEGUNDO DE ASIR
Pgina 8
Inserta una nueva actividad si el numero de regiones es menor a 17,si no es asi muestra mensaje de error
CREATE OR REPLACE TRIGGER num11B BEFORE INSERT ON gestor.actividades FOR EACH ROW DECLARE v_regiones NUMBER; v_user VARCHAR2(25); e_except EXCEPTION; BEGIN SELECT count(*) INTO v_regiones FROM gestor.regiones; SELECT USER INTO v_user FROM DUAL; IF v_regiones < 17 THEN INSERT INTO gestor.CTRL_ACTIVIDADES VALUES (v_user, SYSDATE, 'INTENTO FALLIDO'); RAISE e_except; ELSE DBMS_OUTPUT.PUT_LINE ('Operacion correcta, comprobar tabla CTRL_ACTIVIDADES'); INSERT INTO gestor.CTRL_ACTIVIDADES VALUES (v_user, SYSDATE, 'INSERT'); END IF; EXCEPTION WHEN e_except THEN RAISE_APPLICATION_ERROR(-20001, 'Existen menos de 17 regiones, operacion no permitida'); RAISE; END num11B; /
SEGUNDO DE ASIR
Pgina 9
Intentamos insertar una fila y veremos que nos da error y la tabla que hemos creado al principio del ejercicio ctrl_actividades quedara vacia. SQL> insert into gestor.actividades values (9, 'marketing', 250); insert into gestor.actividades values (9, 'marketing', 250) * ERROR at line 1: ORA-20001: Existen menos de 17 regiones, operacion no permitida ORA-06512: at "GESTOR.NUM11B", line 18 ORA-04088: error during execution of trigger 'GESTOR.NUM11B'
SEGUNDO DE ASIR
Pgina 10
[BASES DE DATOS] 5 de marzo de 2012 12. --> Observe que el usuario AKSEN no tiene ningn tipo de permiso sobre la tabla CTRL_ACTIVIDADES. A pesar de ello, cuando AKSEN intenta insertar una nueva actividad, se insertan valores en la tabla CTRL_ACTIVIDADES? SI. Puede AKSEN consultar esa tabla? NO.
Nos autenticamos como AKSEN SQL> connect aksen Enter password: Connected. Insertamos una nueva fila en la tabla actividades SQL> insert into gestor.actividades values (9, 'marketing', 500); 1 row created.
Como podemos ver, no podemos acceder a la vista, porque no tenemos los derechos, para que as lo pudiramos hacer SQL> select * from gestor.ctrl_actividades; select * from gestor.ctrl_actividades * ERROR at line 1: ORA-00942: table or view does not exist
Comprobaremos que si est la nueva fila en actividades que acaba de insertar AKSEN SQL> select * from gestor.actividades where cod_act=9; COD_ACT NOMBRE_ACT ---------- ------------------------- ---------9 marketing 500 COSTE
SEGUNDO DE ASIR
Pgina 11
Hasta que desde el usuario AKSEN haga commit. SQL> commit; Commit complete.
SEGUNDO DE ASIR
Pgina 12
[BASES DE DATOS] 5 de marzo de 2012 13. --> Suponga que GESTOR quiere insertar una nueva actividad pero el disparador anterior no se lo permite (establezca las condiciones para ello). Para conseguirlo haga que GESTOR desactive el disparador, con la orden ALTER TRIGGER. Mientras el disparador esta desactivado, puede el usuario AKSEN insertar filas en la tabla de Actividades, sin que se ejecute el disparador? SI. Tras insertar la nueva actividad vuelva a activar el disparador y compruebe que realmente est activado para todos los usuarios.
Lo deshabilitamos y hacemos commit, para que tenga efecto: SQL> ALTER TRIGGER num11B DISABLE; Trigger altered.
Ahora una vez que lo hemos desactivado, con el usuario AKSEN insertaremos una nueva fila
SQL> insert into gestor.actividades values (8, 'publicidad', 300); 1 row created.
SEGUNDO DE ASIR
Pgina 13
GESTOR:
SQL> insert into actividades values (8, 'publicidad', 500); insert into actividades values (8, 'publicidad', 500) * ERROR at line 1: ORA-20001: Existen menos de 17 regiones, operacion no permitida ORA-06512: at "GESTOR.NUM11B", line 19 ORA-04088: error during execution of trigger 'GESTOR.NUM11B'
SEGUNDO DE ASIR
Pgina 14
SEGUNDO DE ASIR
Pgina 15
[BASES DE DATOS] 5 de marzo de 2012 14. --> Haga que el usuario GESTOR examine la informacin sobre ese disparador que existe en la vista USER_TRIGGERS del Diccionario de Datos de Oracle (utilice slo las columnas TRIGGER_NAME, STATUS, TRIGGER_TYPE, TRIGGERING_EVENT, TABLE_OWNER y TABLE_NAME). Puede el usuario AKSEN acceder a esa informacin? NO.
Comprobamos con el usuario GESTOR la informacin del trigger que tenemos activo sobre la tabla actividades con el siguiente comando
SQL> select trigger_name, status, trigger_type, triggering_event, table_owner, table_name 2 from user_triggers;
TRIGGER_NAME TABLE_OWNER
TRIGGERING_EVENT
-----------
------------------------------NUM11B
----------------
INSERT
ENABLED GESTOR
Vemos con AKSEN si podemos acceder a esa informacin y como vemos, la respuesta a la pregunta del ejercicio es que NO
SEGUNDO DE ASIR
Pgina 16
[BASES DE DATOS] 5 de marzo de 2012 15. --> Haga que el usuario AKSEN consulte la informacin que tiene disponible en el Diccionario de Datos sobre la tabla de Actividades. Como dicha tabla no le pertenece, dicha tabla no aparece en la vista USER_TABLES. Aparece esa informacin en otra vista llamada ALL_TABLES? SI. Puede el usuario AKSEN consultar las restricciones que operan sobre la tabla de Actividades? SI. En caso afirmativo cuente cuantas restricciones existen sobre esa tabla y observe el tipo de cada una.
Cuando con el usuario AKSEN consultamos la vista sobre la informacin de actividades no veremos nada pero si podemos ver las tablas y si informacin con la vista ALL_TABLES Como podemos ver, veremos las tablas de las que tenemos acceso:
SQL> select table_name from all_tables where owner='GESTOR'; TABLE_NAME -----------------------------PAISES REGIONES CENSO ACTIVIDADES ADOPTAR
SEGUNDO DE ASIR
Pgina 17
SQL> select trigger_name, status, trigger_type, triggering_event, table_owner, table_name 2 from all_triggers 3 where owner='GESTOR';
TRIGGERING_EVENT
-----------------
-----------
INSERT
SEGUNDO DE ASIR
Pgina 18
[BASES DE DATOS] 5 de marzo de 2012 16. --> Asegrese de que existen menos de 5 regiones, para hacer que el disparador genere un error. Haga que el usuario AKSEN intente insertar una nueva actividad que incumpla alguna de las restricciones de integridad de la tabla de Actividades. Lgicamente, la actividad no podr ser insertada pero, cul es el mensaje de error recibido por el usuario, el que genera el disparador, el que genera Oracle por incumplir una restriccin, o ambos? EL DEL DISPARADOR. Qu informacin se ha insertado en la tabla CTRL_ACTIVIDADES?
Bueno, comprobamos lo primero que tenemos menos de 20 regiones y como vemos el numero total de las que tenemos, como ya sabamos era de 16, asique eso se nos muestra al comprobarlo. SQL> select count(*) as total_regiones from regiones; TOTAL_REGIONES -------------16
Con el usuario AKSEN intentamos insertar una fila, que incumpla las condiciones de la INTEGRIDAD REFERENCIAL, en nuestro caso la duplicacin de clave primaria, y como vemos el disparador salta impidindonos realizar la ejecucin, con lo cual lo primero que se realiza es el trigger.
SQL> insert into gestor.actividades values (9, 'fallo', 200); insert into gestor.actividades values (9, 'fallo', 200) * ERROR at line 1: ORA-20001: Existen menos de 17 regiones, operacion no permitida ORA-06512: at "GESTOR.NUM11B", line 19 ORA-04088: error during execution of trigger 'GESTOR.NUM11B'
SEGUNDO DE ASIR
Pgina 19
[BASES DE DATOS] 5 de marzo de 2012 17. --> Inserte nuevas regiones hasta conseguir un mnimo de 5. Tras esto vuelva a probar la insercin del ejercicio anterior, cul es el mensaje de error ahora? Qu informacin se ha insertado ahora en la tabla CTRL_ACTIVIDADES?
Insertar 2 regiones para tener ms de 17 el lmite de mi trigger INSERT INTO regiones VALUES (1, 'reg1', 6000, 32.0, 642051, 20.2); INSERT INTO regiones VALUES (1, 'reg2', 7000, 32.0, 7539618, 15.2);
Repetimos la accin del ejercicio anterior y vemos que ahora, el disparador no salta, porque no tiene por qu hacerlo, y vemos que sin embargo, nos dice lo que tendra que decir, que se esta incumpliendo la condicin de duplicacin de claves. SQL> insert into gestor.actividades values (9, 'fallo', 200); insert into gestor.actividades values (9, 'fallo', 200) * ERROR at line 1: ORA-00001: unique constraint (GESTOR.SYS_C005211) violated
SEGUNDO DE ASIR
Pgina 20
[BASES DE DATOS] 5 de marzo de 2012 18. --> Convierta el disparador en un disparador de tipo AFTER y conteste a la siguiente pregunta. Si al ejecutar una orden SQL sobre una tabla, un disparador AFTER genera un error con RAISE_APPLICATION_ERROR, se ejecuta la orden SQL? o se deshace esa orden a pesar de que el disparador se ejecuta DESPUS de la orden?
Deshabilitamos el trigger de la tabla actividades: SQL> alter trigger num11B disable; Trigger altered.
Crearemos de nuevo el trigger, esta vez para que sea de tipo AFTER. Aumentamos el nmero de regiones que cuenta para que salte el error a 20, ya que si no insertar sin problemas la nueva fila dentro de actividades y no saltar el error.
CREATE OR REPLACE TRIGGER num18 AFTER INSERT ON gestor.actividades FOR EACH ROW DECLARE v_regiones NUMBER; v_user VARCHAR2(25); e_except EXCEPTION; BEGIN SELECT count(*) INTO v_regiones FROM gestor.regiones; SELECT USER INTO v_user FROM DUAL; IF v_regiones < 20 THEN INSERT INTO gestor.CTRL_ACTIVIDADES VALUES (v_user, SYSDATE,'INTENTO FALLIDO'); RAISE e_except; ELSE SEGUNDO DE ASIR Pgina 21
Como vemos, ocurre lo mismo que con el caso BEFORE y tampoco se inserta nada, pues salta el disparador
SQL> insert into actividades values (11, 'prensa', 200); insert into actividades values (11, 'prensa', 200) * ERROR at line 1: ORA-20001: Existen menos de 20 regiones, operacion no permitida ORA-06512: at "GESTOR.NUM18", line 19 ORA-04088: error during execution of trigger 'GESTOR.NUM18'
SEGUNDO DE ASIR
Pgina 22