Uno de los usos de los triggers puede ser el de auditar los cambios que se realizan en los datos de nuestras tablas. Entre la información que podríamos considerar relevante, se encuentra la del autor de dichos cambios. El problema es que, en el contexto de ejecución de un trigger, sólo podemos tener acceso al usuario de base de datos que realiza el cambio, por ejemplo usando una consulta como esta:
SELECT user
INTO vusuario
FROM dual;
Si nuestra aplicación gestiona sus propios usuarios (los cuales supongamos que se conectan a las aplicaciones mediante uno o varios esquemas de Oracle prefijados) no tendremos acceso al usuario real que realiza un cambio dentro del trigger puesto que estos no tienen parámetros. Hoy veremos cómo conseguir que en el contexto de un trigger podamos acceder de forma sencilla y eficiente a la información del usuario real (no el de base de datos) que está realizando un cambio en nuestra tabla y así podamos auditarlo.
Para empezar, necesitaremos desarrollar un paquete que gestione los usuarios que utilizan las aplicaciones. Debería tener al menos algo como esto:
CREATE OR REPLACE PACKAGE datos_usuario
AS
/*******************************************************************************
-- PROCEDURE set_usuarioTriggers
--
-- Descripción: establece la variable interna de usuario para usar en triggers
--
-- Entrada: pe_usuario: usuario de la aplicación
--
------------------------------------------------------------------------------
******************************************************************************/
PROCEDURE set_usuarioTriggers(
pe_usuario IN VARCHAR2 -- 255
);
/******************************************************************************
-- FUNCTION get_usuarioTriggers
--
-- Descripción: establece la variable interna usuario para usar en triggers
--
-- Salida: usuario actual de la aplicación
--
******************************************************************************/
FUNCTION get_usuarioTriggers RETURN VARCHAR2; -- 255
END datos_usuario;
/
CREATE OR REPLACE PACKAGE BODY datos_usuario
AS
-- Variable que contendrá el usuario para usar en triggers
-- Se debe inicializar cada vez que un usuario se conecta
-- A la base de datos desde una aplicación
usuarioTriggers VARCHAR2(255);
PROCEDURE set_usuarioTriggers(pe_usuario IN VARCHAR2) IS
BEGIN
usuarioTriggers := pe_usuario;
END set_usuarioTriggers;
FUNCTION get_usuarioTriggers RETURN VARCHAR2 IS
BEGIN
RETURN usuarioTriggers;
END get_usuarioTriggers;
END datos_usuario;
/
Al inicio de nuestras aplicaciones habrá que invocar la función datos_usuario.set_usuarioTriggers pasándole como parámetro el usuario real que la está utilizando.
Para terminar, desde el trigger de auditoría tendremos acceso al valor de dicho usuario llamando a la función datos_usuario.get_usuarioTriggers. Por ejemplo, algo como esto:
CREATE OR REPLACE TRIGGER UPDATE_JOB_HISTORY
AFTER UPDATE OF job_id, department_id ON employees
FOR EACH ROW
BEGIN
INSERT INTO job_history(
employee_id, start_date, end_date,
job_id, department_id, user_id, date_id)
VALUES(
:OLD.employee_id, :OLD.start_date, :OLD.end_date,
OLD.job_id, :OLD.department_id, datos_usuario.get_usuarioTriggers, SYSDATE);
END;
/
Hola Javier.
ResponderEliminarbuen ejemplo.
Lo he usado aunque bastante información se puede sacar directamente desde la base de datos con
nvl(sys_context('USERENV','HOST'),'SERVIDOR'),
nvl(sys_context('USERENV','OS_USER'),'USUARIO')
directamente en el trigger sin necesidad de modificar la pantalla ni implementar el paquete.
gracias por compartir.
saludos
javier
Pero lo que se obtiene con tu consulta es el usuario de la maquina, mas no el usuario que esta usando la aplicacion.
ResponderEliminar