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

Re: castear variable tipo RECORD a TEXT[]

From: Gerardo Herzig <gherzig(at)fmed(dot)uba(dot)ar>
To: alvherre <alvherre(at)commandprompt(dot)com>, PostgreSQL <pgsql-es-ayuda(at)postgresql(dot)org>
Subject: Re: castear variable tipo RECORD a TEXT[]
Date: 2010-05-28 20:23:29
Message-ID: 4C002641.5010901@fmed.uba.ar (view raw or flat)
Thread:
Lists: pgsql-es-ayuda
alvherre wrote:
> 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?
> 
Hola. Gracias por tu tiempo. Supongo que tendre algunos problemas
extras, debido a que no podre hacer la expansion en forma directa
p.e.
> alvherre=# select tabla, (registro_new::gerardo).* from logtable where
tabla = 'gerardo';
Pues estare auditando multiples tablas (la clausula `where' no sera por
tabla, sino por usuario/periodo de tiempo). Pero supongo que podre hacer
algo con querys dinamicos. Muy util tu ejemplo, muchas gracias por el
trabajo que te tomaste!

Probare y vere como me trata.

Gracias de nuevo!
Gerardo

In response to

Responses

pgsql-es-ayuda by date

Next:From: Fernando SiguenzaDate: 2010-05-28 20:41:01
Subject: Error en consulta: el nombre de columna «max» fue especificado más de una vez
Previous:From: alvherreDate: 2010-05-28 15:19:35
Subject: Re: COPY FROM

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