Excerpts from Gerardo Herzig's message of mié may 26 18:04:22 -0400 2010:
> Hola a todos. No estoy pudiendo castear correctamente una variable
> RECORD a un array.
> 
> Estoy escribiendo un trigger, y me gustaria guardar NEW (y OLD) en forma
> de vectores. Hay alguna manera de hacerlo en plpgsql (quiero decir, sin
> recurrir a contribs)?

¿Por qué no guardas el registro completo serializado a texto, en vez de
procesar atributo por atributo?

alvherre=# create table gerardo (a int, b text, c timestamp);
CREATE TABLE
alvherre=# create function serializa(gerardo) returns text language plpgsql as 
$$ begin return $1::text ; end $$;
CREATE FUNCTION
alvherre=# insert into gerardo values (1, 'gerardo', now());
INSERT 0 1
alvherre=# insert into gerardo values (2, 'herzig', now());
INSERT 0 1
alvherre=# select serializa(gerardo.*) from gerardo;
                serializa                 
------------------------------------------
 (1,gerardo,"2010-05-27 21:06:54.526301")
 (2,herzig,"2010-05-27 21:06:59.989333")
(2 filas)

Me imagino que debe poder hacerse con NEW y OLD también ...

alvherre=# create or replace function trig() returns trigger language plpgsql 
as $$ begin raise notice '%' , NEW::text; return NEW; end ; $$;
CREATE FUNCTION
alvherre=# create trigger gerardo_trig before insert on gerardo for each row 
execute procedure trig();
CREATE TRIGGER
alvherre=# insert into gerardo values (3, 'fmed', now());
NOTICE:  (3,fmed,"2010-05-27 21:10:18.286279")
INSERT 0 1

Esto lo puedes expandir en columnas con * como harías con un registro de una
tabla:

alvherre=# select ('(3,fmed,"2010-05-27 21:10:18.286279")'::gerardo).*;
 a |  b   |             c              
---+------+----------------------------
 3 | fmed | 2010-05-27 21:10:18.286279
(1 fila)



Esto funciona para un trigger genérico:

alvherre=# create table logtable (tabla text, registro_new text);
CREATE TABLE

alvherre=# create or replace function log_trig () returns trigger language 
plpgsql as $$ begin insert into logtable (tabla, registro_new) values 
(tg_relname, new::text); return new; end ; $$;
CREATE FUNCTION

alvherre=# create table franco (a numeric, b inet, c timestamp with time zone);
CREATE TABLE

alvherre=# create trigger franco_trig before insert on franco for each row 
execute procedure log_trig();
CREATE TRIGGER

alvherre=# create trigger gerardo_trig before insert on gerardo for each row 
execute procedure log_trig();
CREATE TRIGGER

alvherre=# insert into gerardo values (3, 'fmed', now());
INSERT 0 1

alvherre=# insert into franco values (42, '192.168.0.3', now());
INSERT 0 1
alvherre=# select * from logtable;
  tabla  |                   registro_new                   
---------+--------------------------------------------------
 gerardo | (3,fmed,"2010-05-27 21:16:30.573531")
 franco  | (42,192.168.0.3,"2010-05-27 21:17:02.494054-04")
(2 filas)


Y puedes expandirlo de esta forma:

alvherre=# select tabla, (registro_new::gerardo).* from logtable where tabla = 
'gerardo';
  tabla  | a |  b   |             c              
---------+---+------+----------------------------
 gerardo | 3 | fmed | 2010-05-27 21:16:30.573531
(1 fila)


No creo que se pueda poner un cast dependiendo del valor de la primera
columna, pero creo que con eso tienes bastante de lo que querías hacer.

A todo esto, ¿alguna razón para no usar tablelog de pgfoundry?

-- 
Álvaro Herrera <alvhe...@commandprompt.com>
The PostgreSQL Company - Command Prompt, Inc.
PostgreSQL Replication, Consulting, Custom Development, 24x7 support
-
Enviado a la lista de correo pgsql-es-ayuda (pgsql-es-ayuda@postgresql.org)
Para cambiar tu suscripci�n:
http://www.postgresql.org/mailpref/pgsql-es-ayuda

Responder a