Variable NEW en una funcion para un trigger

From: "Juan Luis Echeverria" <juanluise(at)usa(dot)net>
To: <pgsql-es-ayuda(at)postgresql(dot)org>
Subject: Variable NEW en una funcion para un trigger
Date: 2008-05-02 16:40:05
Message-ID: 119meBqOM0435M38@cmsapps02.cms.usa.net
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-es-ayuda

Hola:
Solicito me aclaren una duda porfavor: Tengo un trigger BEFORE INSERT FOR
EACH ROW y en la funcion (con PL/pgSQL Postgresql 8.1) que usa en una de sus
lineas tiene la siguiente instruccin:

NEW.idsync008 = new_sync;

en donde idsync008 es un campo de la tabla afectada por el trigger. Esta
instruccin funciona pero la quiero sustituir por esta otra

EXECUTE 'NEW.' || trim(both '' from idsyncxxx) || ' = ' ||
new_idsync || ';';

En donde syncxxx es una variable que ser ercibe como argumento en la funcion
y que contiene el valor 'idsync008'. Esta ultima instruccin no me funciona;
al consultar el log, veo esta descripcion para el error

2008-05-01 23:19:54 ERROR: syntax error at or near "NEW" at character 1
2008-05-01 23:19:54 QUERY: NEW.idsync008 = 15;
2008-05-01 23:19:54 CONTEXT: PL/pgSQL function "sync_marj" line 35 at
execute statement

Mi pregunta es: realmente se puede usar la variable NEW de la forma en que
lo quiero hacer? Y si no, hay alguna otra forma de hacer lo que necesito ?
Lo quiero hacer asi debido a que esta funcion tienen que usarla mas o menos
100 tablas y pues, ya saben, me quiero evitar el tener que hacer 100
funciones en donde lo unico que variara para cada una seran unos cuantos
campos que bien se pudieran recibir como argumentos en dicha funcion. Por
cierto, la variable TG_TABLE_NAME tampoco me funciona pero no me causa
problema ya que puedo recibir el nombre de la tabla en los argumentos de la
funcion.
Gracias por su ayuda.

Saludos.

--------------------
Juan Luis Echeverria
juanluise(at)cresolt(dot)info

PD.
Si sirve de algo, esta es la funcion y el trigger que mencionaba arriba:

CREATE OR REPLACE FUNCTION sync_marj() RETURNS TRIGGER AS $back$
DECLARE
--argumentos
idsyncxxx character(9) = TG_ARGV[0];
syncxxx character(7) = TG_ARGV[1];
tabla_evaluada character(25) = TG_ARGV[2];

--variables a usar dentro del bloque
sync_on usparamweb.usanumrecibos%TYPE;
last_idsync cxabonos.idsync008%TYPE = 0;
new_idsync cxabonos.idsync008%TYPE = 0;
new_sync cxabonos.sync008%TYPE = 0;
new_codinst usinstituciones.codinst%TYPE;
contador_registros bigint = 0;
query1 varchar;

BEGIN

--Si el evento es un insert
IF (TG_OP = 'INSERT') THEN
--Determina si esta activa la sincronizacion en la empresa
del registro a insertar
new_codinst = NEW.codinst;
SELECT usanumrecibos INTO sync_on FROM usparamweb where
codinst = new_codinst;
--indica que si esta activa la replicacion
IF sync_on > 0 THEN

--Trae el ultimo valor de IDSync para la tabla que
se esta recorriendo
query1 := 'SELECT ' || TG_ARGV[0] || ' FROM '||
tabla_evaluada || ' WHERE codinst = ' || new_codinst || ' ORDER BY codinst,
' || TG_ARGV[0] || ' DESC LIMIT 1;';
EXECUTE query1 INTO last_idsync;

--Incremente en 1 el utimo valor encontrado de
idsync008
new_idsync = last_idsync + 1;

--Actualiza los campos IDSync_ y Sync_ de la tabla
que se esta afectando
--NEW.idsync008 = new_idsync;

EXECUTE 'NEW.' || trim(both '' from idsyncxxx) || '
= ' || new_idsync || ';';

--NEW.sync008 = new_sync;
EXECUTE 'NEW.' || trim(both '' from syncxxx) || ' =
' || new_sync || ';';

--crea nuevo registro (si no existe) en USSyncTablas
correspondiente a la tabla que aqui se esta evaluando
--verifica si ya existe el registro correspondiente
a la tabla evaluada
SELECT count(*) INTO contador_registros FROM
ussynctablas WHERE codinst = new_codinst AND tablasync = tabla_evaluada;
--Si no existe el registro se hara un INSERT
IF contador_registros = 0 THEN

--nuevo registro que indica que la tabla
evaluada debe ser sincronizada
INSERT INTO ussynctablas VALUES(new_codinst,
tabla_evaluada, now());
END IF;

END IF;
END IF;
RETURN NEW;
END;
$back$ LANGUAGE plpgsql;

DROP TRIGGER trigger_test ON cxabonos;

CREATE TRIGGER trigger_test BEFORE
INSERT ON cxabonos
--Los primeros 2 argumentos son los campos a modificar; el tercero es el
nombre de la tabla a afectar.
FOR EACH ROW EXECUTE PROCEDURE sync_marj('idsync008','sync008','cxabonos'
);

Responses

Browse pgsql-es-ayuda by date

  From Date Subject
Next Message Alvaro Herrera 2008-05-02 17:35:26 Re: Variable NEW en una funcion para un trigger
Previous Message Fernando Moreno 2008-05-02 16:32:25 Re: Restricciones