Re: Triggers con argumentos

From: "Mario A(dot) Soto Cordones" <mario_soto(at)venezolanadeavaluos(dot)com>
To: <alvherre(at)dcc(dot)uchile(dot)cl>
Cc: <pgsql-es-ayuda(at)postgresql(dot)org>
Subject: Re: Triggers con argumentos
Date: 2004-11-05 19:27:58
Message-ID: 41213.200.35.66.77.1099682878.squirrel@mail.venezolanadeavaluos.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-es-ayuda

Hola Alvaro, lo que quiero hacer es lo siguiente:

Actualizar 1 tabla a partir de otra tabla, pero estas no tienen relacion
entre si, por lo que no puedo utilizar referencia de integridad, sino
fuera sencillo porque le creo una FK y gatillo en evento ON UPDATE. Pero
este no es mi caso:

Inicialmente la función gatillada por el trigger es esta.

CREATE OR REPLACE FUNCTION funcion_act_tabla2" () RETURNS trigger AS'
declare
QRY varchar := '''';
begin
QRY := ''update tabla2 set tabla2.nombre = '''' ||
quote_literal(NEW.nb_nombre) || ''''
where tabla2.empresa= tabla1.co_empresa and tabla2.filial =
tabla1.co_filial and tabla2.codigo = tabla1.nu_activo_fijo'';

execute QRY;
return NEW;
end;
'LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER;

En sintesis lo que quiero hacer es que cuando actualice la tabla1, se
actualicen algunos campos
de la tabla 2.

El trigger que envie anteriormente, fue enviado a la lista de postgres en
ingles por Tom Lane, donde explica que se pueden pasar parametros en un
trigger.

Te adjunto el ejemplo que lo saque de la lista de:
http://archives.postgresql.org/pgsql-sql/2004-07/msg00228.php

Gracias y Saludos

My plpgsql generic trigger function for maintaining referential
integrity with temporal tables now looks as follows:

CREATE FUNCTION func_fk_temporal_trigger () RETURNS "trigger"
AS '
DECLARE
referer_tab text;
referer_col text;
referenced_tab text;
referenced_col text;
stmt varchar(4000);
result record;

BEGIN
referer_tab := TG_ARGV[0];
referer_col := TG_ARGV[1];
referenced_tab := TG_ARGV[2];
referenced_col := TG_ARGV[3];

stmt := '' SELECT id FROM '' || quote_ident(referer_tab);
stmt := stmt || '' WHERE '' || quote_ident(referer_tab) || ''.bis =
''''infinity'''' '';
stmt := stmt || '' AND '' || quote_ident(referer_tab) || ''.'' ||
quote_ident(referer_col) || '' IS NOT NULL'';
stmt := stmt || '' AND NOT EXISTS (SELECT id FROM '' ||
quote_ident(referenced_tab);
stmt := stmt || '' WHERE '' || quote_ident(referer_tab) || ''.'' ||
quote_ident(referer_col) || '' = '' || quote_ident(referenced_tab) ||
''.'' || quote_ident(referenced_col);
stmt := stmt || '' AND '' || quote_ident(referenced_tab) || ''.bis =
''''infinity'''')'';

FOR result IN EXECUTE stmt LOOP
RAISE EXCEPTION ''temporal table referential integrity violation - key
referenced from %.% not found in %.%'', referer_tab, referer_col,
referenced_tab, referenced_col;
END LOOP;

RETURN new;
END;
'
LANGUAGE plpgsql;

And these are some of the trigger definitions which use this function:

CREATE TRIGGER trigger_fk_pns_ug
AFTER INSERT OR UPDATE ON t_pns
FOR EACH ROW
EXECUTE PROCEDURE func_fk_temporal_trigger ('t_pns', 'ug', 't_ug', 'id');

CREATE TRIGGER trigger_fk_ug_pns
AFTER DELETE OR UPDATE ON t_ug
FOR EACH ROW
EXECUTE PROCEDURE func_fk_temporal_trigger ('t_pns', 'ug', 't_ug', 'id');

CREATE TRIGGER trigger_fk_pnspar_pns
AFTER INSERT OR UPDATE ON t_pnspar
FOR EACH ROW
EXECUTE PROCEDURE func_fk_temporal_trigger ('t_pnspar', 'pns',
't_pns', 'id');

CREATE TRIGGER trigger_fk_pnspar_par
AFTER DELETE OR UPDATE ON t_pnspar
FOR EACH ROW
EXECUTE PROCEDURE func_fk_temporal_trigger ('t_pnspar', 'par',
't_par', 'id');

[...]

With this single generic trigger function I can now save myself
of writing (and maintaining) literally dozends of specialized
functions. From what I can say after a few tests it seems to
work quite fine!

Note that I use "FOR result IN EXECUTE stmt LOOP" to process the
results of the dynamic query. To avoid this, I first tried to put
the whole function body including the "RAISE EXCEPTION" statement
into the dynamic query, but it seems the plsql parser doesn't like
this.

May I suggest to put this or a similar example into the
PostgreSQL manual in chapter 35 (Triggers) and/or 37.6.4
(Executing Dynamic Commands)? I'm sure this will save
other peoples time (ok, one can also use google to find
this mail in the archives... ;-)

Regards,

> On Fri, Nov 05, 2004 at 03:06:22PM -0400, Mario A. Soto Cordones wrote:
>
> Hola,
>
>> entonces no existe ninguna forma de pasarle un parametro dinamico a un
>> trigger ?????
>
> Tómate un momento de descanso y nos cuentas con detalles qué es lo que
> quieres hacer. Lo que preguntas no tiene sentido.
>
> --
> Alvaro Herrera (<alvherre[a]dcc.uchile.cl>)
> "Hay que recordar que la existencia en el cosmos, y particularmente la
> elaboración de civilizaciones dentre de él no son, por desgracia,
> nada idílicas" (Ijon Tichy)

Responses

Browse pgsql-es-ayuda by date

  From Date Subject
Next Message Cristian Franceschini 2004-11-05 19:32:20 Instalacion
Previous Message Alvaro Herrera 2004-11-05 19:24:02 Re: Triggers con argumentos