Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » PostgreSQL »

desarrollando mi propio sistema de auditoria para las BD internas

Estas en el tema de desarrollando mi propio sistema de auditoria para las BD internas en el foro de PostgreSQL en Foros del Web. Saludos Estoy tratando de hacer una especie de mini fórmula para que se guarden los registros de mi BD, no está completado, por lo que ...
  #1 (permalink)  
Antiguo 13/07/2009, 16:09
 
Fecha de Ingreso: agosto-2005
Ubicación: Mérida, Venezuela
Mensajes: 732
Antigüedad: 18 años, 8 meses
Puntos: 7
desarrollando mi propio sistema de auditoria para las BD internas

Saludos

Estoy tratando de hacer una especie de mini fórmula para que se guarden los registros de mi BD, no está completado, por lo que falta algunas cosas (como el usuario, la IP de dónde se conecta)

Tabla para guardar unos nombre cualesquiera:
Código:
CREATE TABLE nombres (
    nombres_id serial NOT NULL,
    nombre1 character varying(20),
    nombre2 character varying(20)
);
Tabla para guardar los cambios (léase auditoria):
Código:
CREATE TABLE control (
    tabla character varying NOT NULL,
    campo character varying NOT NULL,
    valor_anterior character varying,
    valor_nuevo character varying,
    opcion character varying NOT NULL,
    ocurrencia time without time zone NOT NULL
);
Función para obtener el nombre del primer campo de una tabla (el nombre puede variar, pero se sabe que es el primer campo):
Código:
CREATE FUNCTION captura(character varying) RETURNS character varying
    AS $_$SELECT column_name FROM information_schema.columns WHERE table_name = $1 AND ordinal_position = 1;$_$
    LANGUAGE sql;
Función disparadora que almacena en la tabla control:
Código:
CREATE FUNCTION controlador() RETURNS "trigger"
    AS $$DECLARE
  nombre_campo character varying;

BEGIN
        
  nombre_campo := captura('TG_RELNAME');
  IF (TG_OP = 'DELETE') THEN
	
    INSERT INTO control (tabla, campo, valor_nuevo, opcion, ocurrencia) VALUES (TG_RELNAME, 'nombre_campo', NEW.nombre_campo, TG_OP, now());
    RETURN OLD;

  ELSIF ((TG_OP = 'UPDATE')  OR (TG_OP = 'INSERT')) THEN

    INSERT INTO control (tabla, campo, valor_nuevo, opcion, ocurrencia) VALUES (TG_RELNAME, 'nombre_campo', NEW.nombres_id, TG_OP, now());
    RETURN NEW;

    END IF;

END;

	$$
    LANGUAGE plpgsql;
Ahora bien, sí en la cónsola ejecuto:
Código:
pruebas=# SELECT captura('nombres');
  captura
------------
 nombres_id
(1 fila)
se observa que funciona. Pero sí, ejecuto un insert sobre la tabla de prueba nombres:
Código:
insert into nombres (nombre1, nombre2) values ('cccc','dddd');
cuando hago una consulta sobre la tabla control, obtengo:
Código:
pruebas=# SELECT * FROM control ;
  tabla  |    campo     | valor_anterior | valor_nuevo | opcion |   ocurrencia
---------+--------------+----------------+-------------+--------+-----------------
 nombres | nombre_campo |                | 27          | INSERT | 17:25:07.398235
(3 filas)
donde se observa que el nombre del primer campo de la tabla, no se está guardando correctamente.

alguna luz? de antemano, gracias
__________________
Gracias de todas todas
-----
Linux!
  #2 (permalink)  
Antiguo 13/07/2009, 20:13
Avatar de huesos52
Colaborador
 
Fecha de Ingreso: febrero-2009
Ubicación: Manizales - Colombia
Mensajes: 5.980
Antigüedad: 15 años, 2 meses
Puntos: 360
Respuesta: desarrollando mi propio sistema de auditoria para las BD internas

Quitale las comillas cacr.

Fijate que dentro del trigger, nombre_campo es el nombre de la variable de tipo character varying, por lo que lleva las comillas implicitas. fijate que está insertando en control, la palabra 'nombre_campo' y no el contenido de la variable con el resultado de la función captura('TG_RELNAME').

Quedaría así:

Cita:
INSERT INTO control (tabla, campo, valor_nuevo, opcion, ocurrencia) VALUES (TG_RELNAME, nombre_campo, NEW.nombres_id, TG_OP, now());
Es ese el error?
Entendí bien?
__________________
Without data, You are another person with an opinion.
W. Edwads Deming
  #3 (permalink)  
Antiguo 14/07/2009, 06:44
 
Fecha de Ingreso: agosto-2005
Ubicación: Mérida, Venezuela
Mensajes: 732
Antigüedad: 18 años, 8 meses
Puntos: 7
Respuesta: desarrollando mi propio sistema de auditoria para las BD internas

Qué tal @huesos52

Ya había intentado con las comillas, asumiendo lo mismo, pero obtengo:
Error de SQL:

ERROR: el valor null para la columna «campo» viola la restricción not null
CONTEXT: sentencia SQL: «INSERT INTO control (tabla, campo, valor_nuevo, opcion, ocurrencia) VALUES ( $1 , $2 , $3 , $4 , now())»
PL/pgSQL function "controlador" line 14 at SQL statement

En la declaración:
INSERT INTO nombres (nombre1, nombre2) VALUES ('carmen','maria')

con lo cual, entreleo, que la función que debería devolver el nombre del campo, no lo está haciendo...
__________________
Gracias de todas todas
-----
Linux!
  #4 (permalink)  
Antiguo 14/07/2009, 07:11
Avatar de huesos52
Colaborador
 
Fecha de Ingreso: febrero-2009
Ubicación: Manizales - Colombia
Mensajes: 5.980
Antigüedad: 15 años, 2 meses
Puntos: 360
Respuesta: desarrollando mi propio sistema de auditoria para las BD internas

un select captura('TG_RELNAME'); te retorna el campo?

Tu dices que esto te funciona.
Cita:
pruebas=# SELECT captura('nombres');
captura
------------
nombres_id
(1 fila)
Que resultado tiene este?
select captura('TG_RELNAME');?
Te devuelve un null?
__________________
Without data, You are another person with an opinion.
W. Edwads Deming
  #5 (permalink)  
Antiguo 14/07/2009, 07:25
 
Fecha de Ingreso: agosto-2005
Ubicación: Mérida, Venezuela
Mensajes: 732
Antigüedad: 18 años, 8 meses
Puntos: 7
Respuesta: desarrollando mi propio sistema de auditoria para las BD internas

sí ejecuto sólo el select captura('TG_RELNAME'); obviamente me devuelve nulo, pero al ser llamado por el triggert, devuelve el nombre de la tabla.

Es posible, que esté utilizando mal esta combinación de funciones SQL y Plpgsql...
__________________
Gracias de todas todas
-----
Linux!
  #6 (permalink)  
Antiguo 14/07/2009, 07:36
Avatar de huesos52
Colaborador
 
Fecha de Ingreso: febrero-2009
Ubicación: Manizales - Colombia
Mensajes: 5.980
Antigüedad: 15 años, 2 meses
Puntos: 360
Respuesta: desarrollando mi propio sistema de auditoria para las BD internas

Se me ocurre, asignes primero a una variable character varying la variable tg_relname.
Posteriormente, llamar en la función nombre_campo := captura(variable_asignada);

No tenía ni idea que era tg_relname, pero según leo, es el nombre de la tabla que invoca el trigger. Si es así, no creo que deba ir entre comillas, por que lo que está haciendo, es enviando la palabra tg_relname a la consulta en information_schema y está comparando ejecutando dicha consulta con la palabra como tal. Por eso te devuelve un null.
Prueba ejecutando así:
nombre_campo := captura(TG_RELNAME);
__________________
Without data, You are another person with an opinion.
W. Edwads Deming
  #7 (permalink)  
Antiguo 14/07/2009, 07:51
 
Fecha de Ingreso: agosto-2005
Ubicación: Mérida, Venezuela
Mensajes: 732
Antigüedad: 18 años, 8 meses
Puntos: 7
Respuesta: desarrollando mi propio sistema de auditoria para las BD internas

http://www.postgresql.org/docs/curre...l-trigger.html

lo de nombre_campo := captura(TG_RELNAME); ya lo probé, y devuelve error, porque captura requiere una cadena, lo de pasarla antes a una variable, ya lo probaré...

Me voy a ausentar un par de horas, mi bebe de 2 añitos tiene una presentación de finde año escolar... la felicidad (de padre) de sentirse orgulloso
__________________
Gracias de todas todas
-----
Linux!
  #8 (permalink)  
Antiguo 14/07/2009, 08:02
Avatar de huesos52
Colaborador
 
Fecha de Ingreso: febrero-2009
Ubicación: Manizales - Colombia
Mensajes: 5.980
Antigüedad: 15 años, 2 meses
Puntos: 360
Respuesta: desarrollando mi propio sistema de auditoria para las BD internas

Te felicito por tu pequeño hijo.

No se si funcione, pero tqmbién puedes probar así:
nombre_campo := captura(TG_RELNAME::character varying);
__________________
Without data, You are another person with an opinion.
W. Edwads Deming
  #9 (permalink)  
Antiguo 14/07/2009, 13:18
 
Fecha de Ingreso: agosto-2005
Ubicación: Mérida, Venezuela
Mensajes: 732
Antigüedad: 18 años, 8 meses
Puntos: 7
Respuesta: desarrollando mi propio sistema de auditoria para las BD internas

así mismo! gracias huesos52

Sigo con la otra parte de la funcioncita...
__________________
Gracias de todas todas
-----
Linux!
  #10 (permalink)  
Antiguo 14/07/2009, 23:45
Avatar de huesos52
Colaborador
 
Fecha de Ingreso: febrero-2009
Ubicación: Manizales - Colombia
Mensajes: 5.980
Antigüedad: 15 años, 2 meses
Puntos: 360
Respuesta: desarrollando mi propio sistema de auditoria para las BD internas

te funcionó?
__________________
Without data, You are another person with an opinion.
W. Edwads Deming
  #11 (permalink)  
Antiguo 20/07/2009, 16:21
 
Fecha de Ingreso: agosto-2005
Ubicación: Mérida, Venezuela
Mensajes: 732
Antigüedad: 18 años, 8 meses
Puntos: 7
Respuesta: desarrollando mi propio sistema de auditoria para las BD internas

Me funcionó nombre_campo := captura(TG_RELNAME::character varying);
Sólo que me conseguí con otro "pequeño" detalle, pero ahora justo, estoy revisando cómo darle la vuelta...
__________________
Gracias de todas todas
-----
Linux!
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 03:35.