Boa tarde amigos,

A um tempo tive um problema relacionado a integridade em uma tabela de
login de terminais, pois havia alguns dados que intercalavam data de
inicio/fim dando assim duplicidades em minhas buscas, exemplo:


id user - ip - data_login - data_logout
1 - 192.168.0.10 - 2013-01-01 00:00:00 - 2013-01-01 10:00:00
3 - 192.168.0.10 - 2013-01-01 08:00:00 - 2013-01-01 14:00:00


No meu select que a chave de busca é o ip e o horario do evento, sempre
teria o erro em um determinado horario.
Mas alem do erro do select, existia o problema haver dois logins do mesmo
terminal em horario conflitante, afinal não posso ter mais de um login por
terminal no mesmo intervalo.

A solução que adotamos foi, criamos uma coluna int que teria o default
sendo 0, e quando houvesse o logout trocaria o valor por um sequencial, e
colocamos um UNIQUE(ip_terminal, lock_controller), desta forma
foi possível evitar mais de um insert na tabela do memo ip no mesmo
intervalo. Usando uma trigger para controlar este processo.

A pergunta é, existe alguma outra técnica que eu poderia ter adotado?

Esta esta sendo uma solução que esta funcionando, claro que venho colocar a
questão na lista para criar novas opções e se melhores ou mais "corretas"
adota-las.

Segue a estrutura da tabela com a trigger que controla o campo
lock_controller.

CREATE TABLE log_usuario
(
  id serial NOT NULL,
  fk_usuario_id integer NOT NULL,
  ref_usuario_login_id integer NOT NULL,
  data_login timestamp without time zone NOT NULL DEFAULT now(),
  data_logout timestamp without time zone,
  ip_terminal inet NOT NULL,
  lock_controller integer NOT NULL DEFAULT 0,
  CONSTRAINT log_usuario_pkey PRIMARY KEY (id),
  CONSTRAINT unique_ip_logged_in UNIQUE (ip_terminal, lock_controller)
);

CREATE TRIGGER log_usuario_pre_trigger
  BEFORE INSERT OR UPDATE
  ON log_usuario
  FOR EACH ROW
  EXECUTE PROCEDURE fn_tg_log_usuario_lockcontroller();


CREATE OR REPLACE FUNCTION fn_tg_log_usuario_lockcontroller()
  RETURNS trigger AS
$BODY$
BEGIN
    IF (TG_OP = 'UPDATE') THEN
        IF NEW.data_logout IS NOT NULL THEN
        NEW.lock_controller =
nextval('log_usuario_ip_lockcontroller'::regclass);
        END IF;
        RETURN NEW;
    ELSIF (TG_OP = 'INSERT') THEN
        NEW.lock_controller = 0;
        RETURN NEW;
    END IF;

    RETURN NULL;
END;
$BODY$
  LANGUAGE plpgsql;


Desde já obrigado a todos.

-- 
Joel Landim Mourão
_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral

Responder a