|
Publicité ' | |||||||||||||||||||||||
|
|
#1 |
|
Invité de passage
![]() Inscription : novembre 2007 Messages : 3 ![]() |
Probleme qui m'a tout l'air très simple ...
Une table de "links" et besoin de déclencher une fonction quand on met à jour la table "links". Deux étapes : 1) faire la fonction , 2) la déclencher. Je butte sur le 1) puis je buterai sur le 2) ! CREATE TABLE links ( linkname character varying(13) NOT NULL, node_a character varying(6), node_b character varying(6) ); ALTER TABLE ONLY links ADD CONSTRAINT pk_links PRIMARY KEY (linkname); CREATE FUNCTION build_linkname( node_a varchar, node_b varchar, OUT linkname varchar) AS $$ BEGIN CASE WHEN node_a < node_b THEN linkname = node_a ||'-'|| node_b ELSE linkname = node_b ||'-'|| node_a END; END; $$ LANGUAGE 'sql' VOLATILE; -> ERROR: syntax error at or near "CASE" at character 101 Là, je ne vois pas , je rame .... Un petit coup de main pour écrire le TRIGGER lors d'un INSERT ou UPDATE ... sera bienvenu aussi ! D'avance merci, Bigre ! |
|
|
00
|
|
|
#2 | ||
|
Membre habitué
![]() Inscription : août 2007 Messages : 128 ![]() |
Commençons déjà par corriger la fonction. À ma connaissance, dans une fonction SQL, il n'est pas possible d'utiliser les noms des variables de la fonction. Il faut utiliser les paramètres de position : $1, $2, $3, etc. D'autre part, et ça c'est certain, une fonction SQL permet d'exécuter une ou plusieurs instructions SQL. CAST n'en est pas une. Il faut donc ajouter un SELECT devant le CAST. Enfin, dernier point : CAST ne permet pas d'affecter une valeur à une variable. En fait, CAST permet directement de renvoyer une valeur. On obtient du coup ceci :
Code :
Ça, c'est pour corriger l'erreur de syntaxe. Maintenant, je ne pense pas que cela fasse ce que tu veux. Je pense que tu veux plutôt une fonction trigger qui va modifier le contenu de la colonne linkname suivant la valeur de node_a et node_b. Premier point : une fonction trigger ne peut pas être écrite en langage SQL. Pratiquement tous les autres langages (de PL/pgsql à PL/ruby) le permettent, mais pas SQL. Donc tu vas devoir ajouter le PL/pgsql au minimum (c'est le plus simple et celui disponible par défaut). Pour ça, tu as toutes les infos sur http://www.postgresql.org/docs/8.2/i...e/plpgsql.html. Pour des infos plus spécifiques à PL/pgsql avec des triggers, tu as cette section : http://www.postgresql.org/docs/8.2/i...l-trigger.html . |
||
|
|
00
|
|
|
#3 |
|
Invité de passage
![]() Inscription : novembre 2007 Messages : 3 ![]() |
Merci pour cette réponse ... je continue à creuser ... le plpgsql, pour une fonction aussi simple ne pose pas de problème.
J'aurais bien vu SELECT $3, CASE .... histoire de savoir où se place le résultat de l'instruction CASE ... mais bon, je vais continuer à lire la doc et à chercher. |
|
|
00
|
|
|
#4 |
|
Membre habitué
![]() Inscription : août 2007 Messages : 128 ![]() |
Le résultat du SELECT est renvoyé immédiatement par la fonction. Une fonction SQL ne fait que renvoyer le résultat de la dernière requête de la fonction.
|
|
|
00
|
|
|
#5 |
|
Invité de passage
![]() Inscription : novembre 2007 Messages : 3 ![]() |
Première étape :
CREATE LANGUAGE plpgsql; La fonction qui compile ... CREATE OR REPLACE FUNCTION buildlinkname() returns TRIGGER AS ' BEGIN IF new.linkname IS NULL THEN IF new.node_a < new.node_b THEN new.linkname := new.node_a ||`-`||new.node_b; ELSE new.linkname := new.node_b ||`-`||new.node_a; END IF; END IF; RETURN new; END; ' LANGUAGE plpgsql; linkname étant Primary Key, le premier test est superflu ... je vais l'enlever. Reste le trigger à mettre au point, pour ne l'exécuter que sur l'enregistremenT en cours d'insertion. CREATE TRIGGER trigger_linkname BEFORE INSERT ON links FOR each row execute procedure buildlinkname(); |
|
|
00
|
Copyright © 2000-2012 - www.developpez.com