Skip site navigation (1) Skip section navigation (2)

diseño 'óptimo' de bitácoras (logs)

From: Marco Antonio Frias Butrón <marcoantoniofrias(at)gmail(dot)com>
To: pgsql-es-ayuda(at)postgresql(dot)org
Subject: diseño 'óptimo' de bitácoras (logs)
Date: 2007-09-18 21:58:59
Message-ID: 33e030de0709181458y3da57e45m292320720449975a@mail.gmail.com (view raw or flat)
Thread:
Lists: pgsql-es-ayuda
Planteo porque pienso que muchos en algún momento hemos tenido que
diseñar bitácoras (logs) para las entidades de nuestro modelo. Ahora
bien, en mi caso yo diseñe una estructura bastante parecida a un
ejemplo que viene en el manual:

http://www.postgresql.org/docs/8.2/static/plpgsql-trigger.html#PLPGSQL-TRIGGER-AUDIT-EXAMPLE

Ejemplo (reducido): Suponiendo que se tiene una entidad llamada
planpago que almacena un monto que se debe pagar 'montototal' en una
fecha 'fechapago', un 'montopagado' que representa el monto que ha
pagado a la fecha (como máximo el montototal) y tiene un estado
REGISTRADO cuando es insertado, pero puede ser anulado entonces se
cambia a ese estado, todo esto pertenece una persona (idpersona). La
estructura de la supuesta entidad:

CREATE TABLE planpago (
    idplanpago bigserial PRIMARY KEY,
    idpersona integer NOT NULL,
    montototal numeric(15,2) NOT NULL,
    montopagado numeric(15,2) NOT NULL,
    fechapago date NOT NULL,
    estado character varying(50) NOT NULL
);

Entonces, quiero guardar el histórico de los cambios de los montos y
fecha, entonces empleando el ejemplo de la 'auditoría' creamos:

CREATE TABLE logplanpago (
    idlogplanpago bigserial PRIMARY KEY,
    accion character varying(1) NOT NULL,
    fecharegistro timestamp without time zone NOT NULL,
    idadministrativo integer NOT NULL,
    idplanpago integer NOT NULL,
    idpersona integer NOT NULL,
    montototal numeric(15,2) NOT NULL,
    montopagado numeric(15,2) NOT NULL,
    fechapago date NOT NULL,
    estado character varying(50) NOT NULL
);

La 'acción' almacena que tipo de cambio sufrió la tupla (I=insert,
U=update o D=delete) y la 'fecharegistro' que es automática al
registrarse, idadministrativo (quien hice el cambio por ahora coloca
1) y el resto los campos de la tabla que se audita. Se inserta
mediante este trigger y función cuando se hace un INSERT, UPDATE o
DELETE en la entidad 'planpago':

CREATE FUNCTION procesar_logplanpago() RETURNS "trigger"
    AS $$
BEGIN

 IF (TG_OP = 'INSERT') THEN
  INSERT INTO logplanpago
   SELECT nextval('logplanpago_idlogplanpago_seq'), 'I', now(), 1, NEW.*;
  RETURN NEW;

 ELSIF (TG_OP = 'UPDATE') THEN
  INSERT INTO logplanpago
   SELECT nextval('logplanpago_idlogplanpago_seq'), 'U', now(), 1, NEW.*;
  RETURN NEW;

 ELSIF (TG_OP = 'DELETE') THEN
  INSERT INTO logplanpago
   SELECT nextval('logplanpago_idlogplanpago_seq'), 'D', now(), 1, OLD.*;
  RETURN OLD;
 END IF;

 RETURN NULL;
END;
$$
    LANGUAGE plpgsql;

CREATE TRIGGER logplanpago_tg
AFTER INSERT OR UPDATE OR DELETE ON planpago
FOR EACH ROW EXECUTE PROCEDURE procesar_logplanpago();

La duda puntual que tengo es si vosotros tienen una mejor solución
para este tema...

-- 
Saludos y abrazos...

Marco A. Frias B.
User Slackware Linux #356229
kmsbii-slackware project member
http://marcoantoniofrias.uni.cc

Responses

pgsql-es-ayuda by date

Next:From: Sebastián VillalbaDate: 2007-09-18 22:14:06
Subject: Re: Repositorio Debian para la version 8.2.4 (OT)
Previous:From: David PrietoDate: 2007-09-18 20:16:53
Subject: Re: Aplicación de Contabilidad

Privacy Policy | About PostgreSQL
Copyright © 1996-2014 The PostgreSQL Global Development Group