Triggers et Schemas 8.4

Lists: pgsql-fr-generale
From: Jean-François TANGUY <jf(dot)tanguy(at)t-yacht(dot)com>
To: pgsql-fr-generale(at)postgresql(dot)org
Subject: Triggers et Schemas 8.4
Date: 2010-11-08 14:11:35
Message-ID: 1289225495.4665.29.camel@fuji
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-fr-generale

Bonjour,

Désolé de faire du bruit sur ce forum si je ne suis pas au bon endroit.

Voila mon souci:

afin de faire une Synchronisation entre 1 base de donnée Postgres et une
autre base de donnée autre que postgres (4D) , J'utilise un trigger
(ci-dessous) dans postgres pour enregistrer dans une table
(sync_synchro) les enregistrements modifiés, ajoutés et supprimés de ma
base postgres. cela fonctionne parfaitement tant que les tables sont
dans le schema public.
je souhaites aujourd'hui ajouter des schemas dans postgres.
Le trigger est bien appelé mais me retourne l'erreur suivante :

---- erreur trigger -------
ERREUR: can't read "tgname": no such variable
CONTEXT: can't read "tgname": no such variable
while executing
"string equal -nocase $tgname sync_synchro"
(procedure "__PLTcl_proc_182994_trigger_182015" line 17)
invoked from within
"__PLTcl_p
----------------------------

Je pense que l'erreur se trouve dans cette ligne

SELECT relname AS tgname FROM pg_class WHERE relfilenode = $TG_relid"

Je cale voyez-vous ou est l'erreur ?

JF

------ TRIGGER Synchro --------

-- Function: sync_trigg()

-- DROP FUNCTION sync_trigg();

CREATE OR REPLACE FUNCTION sync_trigg()
RETURNS trigger AS
$BODY$spi_exec "SELECT CURRENT_USER AS tguser"
spi_exec "SELECT relname AS tgname FROM pg_class WHERE relfilenode =
$TG_relid"

#On oublie les changements pour la table sync_synchro
if {[string equal -nocase $tgname sync_synchro]} { return OK }

# On ne fait pas le trigger s'il s'agit d'une modif on insertion 4D
if { $tguser != "4d" } {
#get PK name

set pk_name ""
spi_exec "SELECT a.attname AS pk_name FROM pg_class c, pg_attribute a,
pg_index i
WHERE c.relname = '$tgname'
AND c.oid=i.indrelid
AND a.attnum > 0
AND a.attrelid = i.indexrelid
AND i.indisprimary='t'"

switch $TG_op {

INSERT {

set pk_value ""
#get PK value
foreach field $TG_relatts {
if {[string equal -nocase [lindex [array get NEW $field] 0]
$pk_name]} {
set pk_value [lindex [array get NEW $field] 1]
break;
}
}

spi_exec "INSERT INTO sync_synchros ( sync_typeupdate, sync_tablename,
sync_from, sync_numidm ) VALUES ( '$TG_op', '$TG_table_name', 'pgsql',
'$pk_value')"

}

UPDATE {

set pk_value ""
#get PK value
foreach field $TG_relatts {
if {[string equal -nocase [lindex [array get OLD $field] 0]
$pk_name]} {
set pk_value [lindex [array get OLD $field] 1]
break;
}
}

spi_exec "INSERT INTO sync_synchros ( sync_typeupdate,
sync_tablename, sync_from, sync_numidm ) VALUES ('$TG_op',
'$TG_table_name', 'pgsql','$pk_value')"

}

DELETE {

set pk_value ""
#get PK value
foreach field $TG_relatts {
if {[string equal -nocase [lindex [array get OLD $field] 0]
$pk_name]} {
set pk_value [lindex [array get OLD $field] 1]
break;
}
}

spi_exec "INSERT INTO sync_synchros (sync_typeupdate,
sync_tablename, sync_from, sync_numidm ) VALUES ( '$TG_op',
'$TG_table_name', 'pgsql', '$pk_value' )"

}

}
}

return OK

$BODY$
LANGUAGE pltcl VOLATILE
COST 100;
ALTER FUNCTION sync_trigg() OWNER TO jf;


From: Dimitri Fontaine <dimitri(at)2ndQuadrant(dot)fr>
To: jf(dot)tanguy(at)t-yacht(dot)com
Cc: pgsql-fr-generale(at)postgresql(dot)org
Subject: Re: Triggers et Schemas 8.4
Date: 2010-11-08 15:20:59
Message-ID: m21v6v7sf8.fsf@2ndQuadrant.fr
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-fr-generale

Jean-François TANGUY <jf(dot)tanguy(at)t-yacht(dot)com> writes:
> afin de faire une Synchronisation entre 1 base de donnée Postgres et une
> autre base de donnée autre que postgres (4D) , J'utilise un trigger
> (ci-dessous) dans postgres pour enregistrer dans une table
> (sync_synchro) les enregistrements modifiés, ajoutés et supprimés de ma
> base postgres. cela fonctionne parfaitement tant que les tables sont
> dans le schema public.

J'utiliserais PGQ afin de s'occuper de la partie trigger et gestion de
la file d'attente, avec un "consumer" spécialisé :

http://wiki.postgresql.org/wiki/PGQ_Tutorial

> (procedure "__PLTcl_proc_182994_trigger_182015" line 17)
>
> Je cale voyez-vous ou est l'erreur ?

À la ligne 17 de la fonction, comme indiqué

> WHERE c.relname = '$tgname'

Maintenant c'est du pltcl je n'ai pas l'habitude de cela, et pas le
temps d'aller plus loin dans l'investigation du problème.

Bonne chance,
--
Dimitri Fontaine
http://2ndQuadrant.fr PostgreSQL : Expertise, Formation et Support