E16 - Diseño de Sistemas de Bases de Datos Boletín 3

Anuncio
E16 - Diseño de Sistemas de Bases de Datos
Boletín 3
Nombre:_____________________________________________________________________________________________
1.
Esta práctica está dedicada a la creación de disparadores sobre sentencias DDL (lenguaje de definición de datos) y sobre
eventos de la Base de Datos. También veremos la ejecución de trabajos de forma periódica.
A continuación se detallan los eventos que pueden se capturados, así como los procedimientos del paquete DBMS_JOB:
Sobre sentencias DDL
ALTER
ANALYZE
ASSOCIATE STATISTICS
AUDIT
COMMENT
CREATE
DISASSOCIATE STATISTICS
DROP
GRANT
NOAUDIT
RENAME
REVOKE
TRUNCATE
DDL
Sobre eventos de la BD
SERVERERROR
LOGON
LOGOFF
STARTUP
SHUTDOWN
SUSPEND
DBMS_JOB
SUBMIT
REMOVE
CHANGE
WHAT
NEXT_DATE
INSTANCE
INTERVAL
BROKEN
RUN
USER_EXPORT
La documentación en línea con todos los detalles puede ser consultada en
http://anubis/~oracle/manuales/
2.
Esta sesión se realizará sobre Oracle9i. Para acceder a esta versión hay que entrar en SQL*Plus con el siguiente nombre
de usuario, sustituyendo las X por el número correspondiente:
alXXXXXX/alXXXXXX@pc
Es necesario volver a crear las tablas utilizadas en el Boletín 1, ejecutando
SQL> start /home/inf/dba/PUBLIC/E16/crea_tablas.sql
3.
Vamos a empezar definiendo 2 disparadores para poder controlar quien se conecta a la base de datos y cuánto tiempo
permanece conectado. Para ello, crearemos un disparador sobre el evento LOGON y otro sobre LOGOFF que actualice la
fila del LOGON correspondiente.
Para realizar este punto, teclearemos el siguiente código en un fichero llamado trg_bd_1.sql
create or replace trigger al000000_01
after logon on schema
begin
insert into p_logins (owner, f_inicio, ip, session_id)
values (ora_login_user, sysdate, nvl(ora_client_ip_address,'Desconocida'),
dbms_session.unique_session_id);
end;
/
create or replace trigger al000000_02
before logoff on schema
begin
update p_logins set f_fin = sysdate
where owner = ora_login_user and
session_id = dbms_session.unique_session_id;
end;
/
Una vez creado el fichero, lo ejecutaremos desde el prompt del SQL*Plus:
SQL> start trg_bd_1
4.
Una vez creados los 2 disparadores, procedemos a realizar las correspondientes pruebas:
SQL> connect alXXXXXX/********@pc
SQL> connect alXXXXXX/********@pc
Cada connect implica el cierre de la conexión anterior. Para ver si realmente se ha almacenado las conexiones,
realizaremos la consulta siguiente:
select owner, to_char(f_inicio, 'dd-mm-yyyy hh24:mi:ss'),
to_char(f_fin, 'dd-mm-yyyy hh24:mi:ss')
from p_logins;
¿Se obtiene la información esperada?........................................................................................................................................
...................................................................................................................................................................................................
...................................................................................................................................................................................................
5.
El siguiente disparador que vamos a definir, va a permitir registrar todos los errores que produzcamos. Para ello lo
dispararemos sobre el evento SERVERERROR y restringido a nuestro esquema (SCHEMA).
Para realizar este punto, teclearemos el siguiente código en un fichero llamado trg_bd_2.sql
create or replace trigger al000000_03
after servererror on schema
begin
insert into p_errores (fecha, error_texto)
values (sysdate, dbms_utility.format_error_stack);
end;
/
Una vez creado el fichero, lo ejecutaremos desde el prompt del sqlplus:
SQL> start trg_bd_2
6.
Para realizar las pruebas sobre el disparador anterior, podemos lanzar alguna sentencia simple, o incluso alguna sentencia
de la sesión anterior.
desc patata
drop table patata;
insert into p_puntuaciones (usu_usuario, ite_id, puntuacion)
values (‘al000000’, 3, 7);
¿Qué consulta haríamos para comprobar su funcionamiento?...................................................................................................
...................................................................................................................................................................................................
...................................................................................................................................................................................................
7.
A continuación, vamos a proceder a la creación de un trabajo que guardaremos en la cola de trabajos. Este trabajo, lanzará
un procedimiento, que conectándose a anubis, nos mandará un e-mail con un listado de las conexiones que se han
realizado. El procedimiento se encuentra en un fichero que hay que ejecutar:
SQL> start /home/inf/dba/PUBLIC/E16/crea_proc_mail.sql
8.
Una vez creado el procedimiento, teclearemos el bloque PL/SQL siguiente. El trabajo almacenado se ejecutará según el
campo NEXT_DATE (tercer parámetro), y se ejecutará periódicamente según formula definida en INTERVAL (cuarto
parámetro).
declare
job number;
begin
dbms_job.submit(job, 'manda_mail;', sysdate, 'sysdate + 1/(24*12)');
commit;
end;
/
¿Se ha ejecutado el trabajo?.......................................................................................................................................................
...................................................................................................................................................................................................
...................................................................................................................................................................................................
9.
Para comprobar que se ha almacenado correctamente y cuales son sus parámetros, podemos realizar la siguiente consulta:
select job, to_char(next_date,'dd-mm-yyy hh24:mi:ss'), interval, what
from user_jobs;
¿Se obtiene la fila con los datos previstos?................................................................................................................................
...................................................................................................................................................................................................
...................................................................................................................................................................................................
10. El trabajo que hemos creado, se ejecutará a intervalos de 5 minutos, lo cual puede ser un poco engorroso, por lo que
procederemos a modificar su frecuencia de disparo para situarla a sólo una vez al día. El <número de job> que hay que
indicar, es el obtenido en la consulta anterior (JOB).
begin
dbms_job.interval(<número de job>, 'trunc(sysdate) + 1');
end;
/
¿Sabrías eliminar el trabajo de la cola? .....................................................................................................................................
...................................................................................................................................................................................................
...................................................................................................................................................................................................
ANEXO A
ANEXO B:
DBMS_JOB.SUBMIT (
job
OUT BINARY_INTEGER,
what
IN VARCHAR2,
next_date IN DATE DEFAULT sysdate,
interval IN VARCHAR2 DEFAULT 'null',
no_parse IN BOOLEAN DEFAULT FALSE,
instance IN BINARY_INTEGER DEFAULT any_instance,
force
IN BOOLEAN DEFAULT FALSE);
DBMS_JOB.INTERVAL (
job
IN BINARY_INTEGER,
interval IN VARCHAR2);
DBMS_JOB.REMOVE (
job
IN BINARY_INTEGER);
ANEXO C
create or replace procedure manda_mail
is
conn
len
res
usuario
cuerpo
utl_tcp.connection;
number(6);
varchar2(3);
varchar2(30);
varchar2(2000);
cursor cur is
select rpad(owner,20)||
rpad('Conexiones: '||to_char(count(*)),30)||
'Minutos: '||to_char(round(sum((f_fin-f_inicio)*60*24))) linea
from p_logins
group by owner;
begin
select user into usuario from dual;
cuerpo := '';
for r in cur loop
cuerpo := cuerpo || r.linea || chr(10);
end loop;
cuerpo := cuerpo || '.' || chr(10);
conn := utl_tcp.open_connection ('anubis.uji.es', 25);
len := utl_tcp.write_line(conn, 'HELO anubis.uji.es');
res := substr(utl_tcp.get_line(conn),1,3);
len := utl_tcp.write_line(conn, 'MAIL FROM: [email protected]');
res := substr(utl_tcp.get_line(conn),1,3);
len := utl_tcp.write_line(conn, 'RCPT TO: '||usuario||'@alumail.uji.es');
res := substr(utl_tcp.get_line(conn),1,3);
len := utl_tcp.write_line(conn, 'DATA');
res := substr(utl_tcp.get_line(conn),1,3);
len := utl_tcp.write_line(conn, cuerpo);
res := substr(utl_tcp.get_line(conn),1,3);
len := utl_tcp.write_line(conn, 'QUIT');
res := substr(utl_tcp.get_line(conn),1,3);
utl_tcp.close_connection(conn);
end;
/
Descargar