PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

Vous n'êtes pas identifié(e).

#1 Re : PL/pgSQL » [postgresql9.0] Migration de base et triggers » 13/10/2011 15:11:56

mg

ok je pige, dans ce cas, le code initial n'était effectivement pas juste vu l'objectif que j'avais (c'est normal, c'est le mien tongue).

la piste du \do n'est pas mal non plus, car je viens de m'apercevoir que je n'ai même pas l'opérateur = dans ma liste. Je vais voir à corriger ça. Un postgis installé bien complet, ça sera quand même mieux pour bosser.

#2 Re : PL/pgSQL » [postgresql9.0] Migration de base et triggers » 13/10/2011 14:33:31

mg

Bonjour,

Je suppose que postgis 1.5 est bien installé., car ce n'est pas qui l'ai fait. Je vais vérifier ça avec l'informaticien.
Pour la commande \do dans psql, je me fait jeter proprement, je  pense que je ne dois pas bien la taper (variable non reconnue ???)

Par contre la solution  NOT ST_Equals(OLD.the_geom,NEW.the_geom) de rjuju a l'air de bien fonctionner. Je vais creuser par là pour modifier mes triggers.

Merci

#3 PL/pgSQL » [postgresql9.0] Migration de base et triggers » 07/10/2011 16:46:30

mg
Réponses : 8

Bonjour,

Je viens de passer ma base de données de postgresql 8.4 à 9.0. Pas de soucis pour la migration des tables en elles mêmes, par contre certains de mes triggers ne fonctionnent plus.

Par exemple

BEGIN
--Si la géométrie a été modifiée ou si x ou y sont vides
IF (NEW.the_geom != OLD.the_geom) OR OLD.x IS NULL OR OLD.y IS NULL THEN -- alors on modifie les colonnes x et y
NEW.x=x(astext(NEW.the_geom));
NEW.y=y(astext(NEW.the_geom));
ELSE -- si la géométrie n'a pas été mofidiée
-- mais si on a modifié manuellement les colonnes x et y
IF (NEW.x != OLD.x) OR (NEW.y != OLD.y) THEN  -- alors on intègre la nouvelle géométrie à partir des nouvelles valeurs de x et y
NEW.the_geom=geometryfromtext('POINT('||NEW.x||' '||NEW.y||')',2154);
END IF;
END IF;
RETURN NEW;
END;

Si je modifie un objet de la table, j'obtiens :

Erreur lors de l'exécution du lien centre pour la raison suivante :
ERREUR: l'opérateur n'est pas unique : geometry <> geometry
LINE 1:SELECT (NEW.the_geom != OLD.the_geom) OR OLD.x ...

HINT: N'a pas pu choisir un meilleur candidat pour l'opérateur. Vous devez ajouter une conversion explicite de type.

Je n'ai rien trouvé dans la documentation concernant une modification dans l'écriture des triggers, l'un de vous a-t-il une piste ??
A noter que lors de la validation de mon trigger suite à des modifs d'essai, je n'ai pas de message d'erreur, donc le code a l'air valide.

merci

#4 Re : Optimisation » vue modifiable » 04/03/2009 11:06:53

mg

Merci, cela semble fonctionner comme ça.
Par contre, créer une fonction qui ne renvoie rien ne fonctionne pas car la fonction qui ne renvoie pas le type trigger ne reconnaît pas l'état NEW/OLD de l'enregistrement (et ça ne me paraît pas logique de passer les 67 colonnes de ma vue en paramètres) =>

Code :
create or replace function insert_troncon1() RETURNS void AS $insert_troncon$
DECLARE
var_gipsi varchar;
BEGIN
var_gipsi := NEW.id_gipsi;
[...]

Erreur :
ERROR:  NEW used in query that is not in a rule
QUERY:  SELECT  NEW.id_gipsi
CONTEXT:  SQL statement in PL/PgSQL function "insert_troncon1" near line 6

Du coup, j'ai essayé en remplaçant var_gipsi:=NEW.id_gipsi par SET var_gipsi = new.id_gipsi
erreur :
ERROR:  syntax error at or near "$1"
LINE 1: SET  $1  = NEW.id_gipsi
             ^
QUERY:  SET  $1  = NEW.id_gipsi
CONTEXT:  SQL statement in PL/PgSQL function "insert_troncon1" near line 4

#5 Re : Optimisation » vue modifiable » 03/03/2009 10:40:57

mg

J'ai créé la fonction suivante, cependant, je n'arrive pas à la lancer à partir de ma règle -> 'create rule v_troncon_route_i as on insert to v_cp_troncon_route do instead for each row execute procedure insert_troncon()'
Je mélange peut-être encore les deux langages, mais alors je ne vois pas comment lancer une fonction à partir de ma règle.

create or replace function insert_troncon() RETURNS "trigger" AS $insert_troncon$

BEGIN

-- Tester si ID_GIPSI existe dans la table CP_ROUTE

IF var_gipsi IS NULL THEN

     SET var_gipsi = '-1';

ELSIF (NOT EXISTS (SELECT id_gipsi FROM cp_route WHERE id_gipsi=var_gipsi)) THEN

    INSERT INTO cp_route (id_gipsi,nom,nom_carto,nature,appellations_multiples,code_commune,code_insee,er,dossier_er,quartier1,quartier2,
    motcle01,motcle02,motcle03,motcle04,motcle05,motcle06,motcle07,motcle08,motcle09)
    values (var_gipsi,NEW.nom,NEW.nature||' '||NEW.nom,NEW.nature,NEW.appellations_multiples,NEW.code_commune,NEW.code_insee,NEW.er,NEW.dossier_er,
    NEW.quartier1,NEW.quartier2,NEW.motcle01,NEW.motcle02,NEW.motcle03,NEW.motcle04,NEW.motcle05,NEW.motcle06,NEW.motcle07,NEW.motcle08,
    NEW.motcle09);

END IF;

-- Tester la présence d'un champ indisponibilté rempli

IF (debut_indisponible IS NOT NULL OR fin_indisponible IS NOT NULL  OR indisponible IS NOT NULL OR motif IS NOT NULL) THEN

    INSERT INTO cp_troncon_indisponible (id_troncon,debut_indisponible,fin_indisponible,indisponible,motif)
    values (NEW.id_troncon,NEW.debut_indisponible,NEW.fin_indisponible,NEW.indisponible,NEW.motif);

END IF;

-- Remplir la table CP_TRONCON_ROUTE
INSERT INTO cp_troncon_route (
id_gipsi,
id_troncon,
pid,
classement_administratif,
the_geom,
[...])
values (
NEW.id_gipsi,
NEW.id_troncon,
NEW.pid,
NEW.classement_administratif,
NEW.the_geom,
[...]);
RETURN NEW;

END;

$insert_troncon$ LANGUAGE 'plpgsql' VOLATILE;

ALTER FUNCTION insert_troncon() OWNER TO postgres;

#6 Optimisation » vue modifiable » 02/03/2009 18:35:46

mg
Réponses : 14

Bonjour,

J'essaie de créer une vue modifiable dans ma base postgresql. J'ai déjà créé ma vue à partir de 3 tables (cp_route;cp_troncon_route;cp_troncon_indispo).
J'ai voulu créer une règle  (sur l'insert pour commencer), mais j'ai l'impression que "CREATE RULE" ne supporte pas les conditions dans les instructions. J'ai aussi essayé de passer les instructions dans une fonction "trigger" puis d'appeler la fonction à partir de ma règle, mais ça ne fonctionne pas.
Je mets ci-dessous le contenu de ma règle d'insert. Si vous voyez le problème ou bien si vous connaissez une autre solution... merci

create or replace rule v_cp_troncon_route_i as
on insert to v_cp_troncon_route
do instead (

--Tester l'état de id_gipsi et s'il n'existe pas dans la table CP_ROUTE, créer la route correspondante

IF NEW.id_gipsi IS NULL THEN

     SET var_gipsi = '-1';

ELSIF (NOT EXISTS (SELECT id_gipsi FROM cp_route WHERE id_gipsi=NEW.id_gipsi)) THEN

    INSERT INTO cp_route (id_gipsi,nom,nom_carto,nature,appellations_multiples,code_commune,code_insee,er,dossier_er,quartier1,quartier2,
    motcle01,motcle02,motcle03,motcle04,motcle05,motcle06,motcle07,motcle08,motcle09)
    values (NEW.id_gipsi,NEW.nom,NEW.nature||' '||NEW.nom,NEW.nature,NEW.appellations_multiples,NEW.code_commune,NEW.code_insee,NEW.er,NEW.dossier_er,
    NEW.quartier1,NEW.quartier2,NEW.motcle01,NEW.motcle02,NEW.motcle03,NEW.motcle04,NEW.motcle05,NEW.motcle06,NEW.motcle07,NEW.motcle08,
    NEW.motcle09);
    SET var_gipsi = NEW.id_gipsi;
ELSIF
    SET var_gipsi = NEW.id_gipsi;
END IF;

-- Tester la présence d'un champ indisponibilté rempli et compléter la table cp_troncon_indispo

IF (debut_indisponible IS NOT NULL OR fin_indisponible IS NOT NULL  OR indisponible IS NOT NULL OR motif IS NOT NULL) THEN

    INSERT INTO cp_troncon_indispo (id_troncon,debut_indisponible,fin_indisponible,indisponible,motif)
    values (NEW.id_troncon,NEW.debut_indisponible,NEW.fin_indisponible,NEW.indisponible,NEW.motif);

END IF;

-- Remplir la table CP_TRONCON_ROUTE
INSERT INTO cp_troncon_route (
id_gipsi,
id_troncon,
pid,
classement_administratif,
the_geom,
[...])
values (
var_gipsi,
NEW.id_troncon,
NEW.pid,
NEW.classement_administratif,
NEW.the_geom,
[...]);
);

Pied de page des forums

Propulsé par FluxBB