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" <[email protected]>
Para: [email protected]
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. 
-
Enviado a la lista de correo pgsql-es-ayuda ([email protected])
Para cambiar tu suscripci�n:
http://www.postgresql.org/mailpref/pgsql-es-ayuda

Responder a