Re: error en ejecucion de trigger

From: Gustavo Garay <listas(at)shitech(dot)com(dot)py>
To: pgsql-es-ayuda(at)postgresql(dot)org
Subject: Re: error en ejecucion de trigger
Date: 2011-04-18 21:34:26
Message-ID: 10480918.2.1303162466672.JavaMail.root@web-mail
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-es-ayuda


El triger tiene que ser accionado x ROW no STATEMENT, como definiste, solo TRUNCATE es accionado como STATEMENT

Y x regla los triger de audotoria para log tiene que ser AFTER

Saludos

Gustavo Garay

----- Mensaje original -----
De: "Miguel Torres" <mtorres066(at)gmail(dot)com>
Para: pgsql-es-ayuda(at)postgresql(dot)org
Enviados: Lunes, 18 de Abril 2011 17:19:21
Asunto: [pgsql-es-ayuda] error en ejecucion de trigger

Hola amigos de la lista,

Tengo un problema con la ejecucion de un Trigger, explico: Busco con un trigger registrar todos los movimientos de ciertas tablas (auditoria de movimientos)

Tengo la sig. funcion que es llamada por el trigger:
CREATE OR REPLACE FUNCTION procesa_usuario_audit() RETURNS trigger AS
$$
DECLARE
BEGIN
-- Crea un registro en usuario_audit para reflejar las operaciones
-- realizadas en usuario utiliza las variables especiales TG_OP
-- para efectuar la operacion
IF (TG_OP = 'DELETE') THEN
INSERT INTO usuario_audit SELECT nextval('usuario_audit_id_usuario_audit_seq'::regclass), 'D', now(), user, OLD.id_usuario;
RETURN OLD;
ELSIF (TG_OP = 'UPDATE') THEN
INSERT INTO usuario_audit SELECT nextval('usuario_audit_id_usuario_audit_seq'::regclass), 'U', now(), user, NEW.id_usuario;
RETURN NEW;
ELSIF (TG_OP = 'INSERT') THEN
INSERT INTO usuario_audit SELECT nextval('usuario_audit_id_usuario_audit_seq'::regclass), 'I', now(), user, NEW.id_usuario;
RETURN NEW;
END IF;
RETURN NULL; -- el resultado es ignorado puesto que este es un trigger AFTER
END;
$$
LANGUAGE plpgsql;

Esta es la tabla original principal a donde amarro el trigger: tabla usuario

Columna | Tipo | Modificadores
-----------------+--------------------------------+---------------------------------------------------------------
id | integer | not null valor por omisin nextval('usuario_id_seq'::regclass)
id_usuario | integer | not null
nombre | character varying |
apellido | character varying |
puesto | character varying |
depto | character varying |
num_serv_sol | integer |
ultimo_ticket | integer |
usuario_windows | character varying |
clave_windows | character varying |
email | character varying |
usuario_correo | character varying |
clave_correo | character varying |
ext | integer |
tipo_linea | character varying |
tel_libre | boolean |
celular | numeric(14,0) |
plan_celular | character varying |
foto | bytea |
userbd | name | not null valor por omisin getpgusername()
timeupdate | timestamp(0) without time zone | not null valor por omisin now()
-ndices:
"usuario_celular_key" UNIQUE, btree (celular)
"usuario_id_key" UNIQUE, btree (id)
"usuario_id_usuario_key" UNIQUE, btree (id_usuario)
"usuario_usuario" UNIQUE, btree (id_usuario, nombre, apellido, email)
Referenciada por:
TABLE "carpetas" CONSTRAINT "carpetas_usuario" FOREIGN KEY (id_usuario) REFERENCES usuario(id_usuario) ON UPDATE CASCADE
TABLE "equipo" CONSTRAINT "equipo_usuario" FOREIGN KEY (id_usuario) REFERENCES usuario(id_usuario) ON UPDATE CASCADE
TABLE "internet" CONSTRAINT "internet_fk" FOREIGN KEY (id_usuario) REFERENCES usuario(id_usuario) ON UPDATE CASCADE
Triggers:
grabar_usuario AFTER INSERT OR DELETE OR UPDATE ON usuario FOR EACH STATEMENT EXECUTE PROCEDURE procesa_usuario_audit()

Este es el trigger:
CREATE TRIGGER grabar_usuario AFTER INSERT OR DELETE OR UPDATE ON usuario FOR EACH STATEMENT EXECUTE PROCEDURE procesa_usuario_audit();

Esta es la tabla donde ingresa los datos el trigger: tabla usuario_audit

Columna | Tipo | Modificadores
------------+-----------------------------+-----------------------------------------------------------------------------------
id_audit | integer | not null valor por omisin nextval('usuario_audit_id_usuario_audit_seq'::regclass)
operacion | character(1) | not null
timeupdate | timestamp without time zone | not null
userbd | text | not null
id_usuario | integer | not null
-ndices:
"usuario_audit_pkey" PRIMARY KEY, btree (id_audit)

------------------------------------------------------------------------------------------------------------------------
Este es el mensaje de error:
Ejecuto un update o insert en la tabla usuario:

soporte=# update usuario set depto = 'Administracion' where id_usuario = 514;
ERROR: el registro «new» no ha sido asignado aún
DETALLE: La estructura de fila de un registro aún no asignado no está determinado.
CONTEXTO: función PL/pgSQL «procesa_usuario_audit» en la línea 10 en sentencia SQL
soporte=#

Ejecuto la instruccion de manera directa del trigger (ver funcion):
soporte=# INSERT INTO usuario_audit SELECT nextval('usuario_audit_id_usuario_audit_seq'::regclass),'I', now(), user, 8;
INSERT 92551 1
soporte=# INSERT INTO usuario_audit SELECT nextval('usuario_audit_id_usuario_audit_seq'::regclass),'U', now(), user, 8;
INSERT 92552 1
(resultado OK)

reviso la tabla afectada:
soporte=# select * from usuario_audit;
id_audit | operacion | timeupdate | userbd | id_usuario
----------+-----------+-------------------------+--------+------------
10 | I | 2011-04-18 15:05:05.917 | miguel | 8
11 | I | 2011-04-18 15:05:11.839 | miguel | 8
12 | U | 2011-04-18 15:10:57.464 | miguel | 8
(3 filas)

No entiendo que pasa, ya realize pruebas con BEFORE y no funciona, en teoria funciona con AFTER segun ejemplos tomados en la red (Yo practique con los ejemplos y funcionan con AFTER)
Alguna sugerencia?

Desde ya, muchas gracias.

soporte=# select * from version();
version
-------------------------------------------------------------
PostgreSQL 8.4.4, compiled by Visual C++ build 1400, 32-bit
(1 fila)
desde Win XP Pro
--
Miguel Angel Torres
Culiacan, Sin.

In response to

Browse pgsql-es-ayuda by date

  From Date Subject
Next Message Alvaro Herrera 2011-04-18 21:38:39 Re: error en ejecucion de trigger
Previous Message Miguel Torres 2011-04-18 21:19:21 error en ejecucion de trigger