Vous n'êtes pas identifié(e).
- Contributions : Récentes | Sans réponse
Pages : 1
#1 15/10/2008 16:05:11
- Katagoto
- Membre
Fonctions variables et arguments
Bonjour à toutes et à tous,
Je suis nouveau, j'ai tenter de crrée une fonction, mais je ne sais pas comment utiliser les arguments :
CREATE FUNCTION ri_ajoute_fils(IN tabletype character, IN pk_parent integer, IN nom character) RETURNS void AS
$BODY$
SELECT * FROM $NomTable AS C WHERE C.pk_categorie=$PkParent;
UPDATE $NomTable
SET BordDroit = BordDroit + 2
WHERE BordDroit >= C.BordDroit;
UPDATE $NomTable
SET BordGauche = BordGauche + 2
WHERE B.BordGauche >= C.BordGauche;
INSERT INTO $NomTable (BordDroit, BordGauche, nom) VALUES (C.BordDroit, C.BordDroit+1, $nom);$BODY$
LANGUAGE 'sql' VOLATILE;
Comment faire ?
Par avance merci de votre aide
PS : J'ai la V8.3.4 de PostGreSQL et j'ai fait cette fonction avec PgAdmin III
Hors ligne
#2 18/10/2008 11:23:12
- Katagoto
- Membre
Re : Fonctions variables et arguments
Bon,
J'ai tenté autre chose, quelqu'un peut m'expliquer pourquoi ça plante ?
Par avance merci de votre aide :
CREATE FUNCTION ri_ajoute_fils(IN character, IN integer, IN character) RETURNS void AS
$BODY$SELECT * FROM $1 AS C WHERE C.pk_categorie=$2;
UPDATE $1
SET BordDroit = BordDroit + 2
WHERE BordDroit >= C.BordDroit;
UPDATE $1
SET BordGauche = BordGauche + 2
WHERE B.BordGauche >= C.BordGauche;
INSERT INTO $1 (BordDroit, BordGauche, nom) VALUES (C.BordDroit, C.BordDroit+1, $3);$BODY$
LANGUAGE 'sql' VOLATILE;
Hors ligne
#3 18/10/2008 11:43:43
- gleu
- Administrateur
Re : Fonctions variables et arguments
Donner le message d'erreur pourrait aider.
Guillaume.
Hors ligne
#4 18/10/2008 12:00:00
- Katagoto
- Membre
Re : Fonctions variables et arguments
Oui, ça peut servir :
ERREUR: erreur de syntaxe sur ou près de « $1 »
LIGNE 2 : $BODY$SELECT * FROM $1 AS C WHERE C.pk_categorie=$2;
^
********** Erreur **********
ERREUR: erreur de syntaxe sur ou près de « $1 »
État SQL :42601
Caractère : 108
Hors ligne
#5 18/10/2008 12:08:01
- gleu
- Administrateur
Re : Fonctions variables et arguments
Les paramètres de la fonction ne peuvent pas figurer au niveau de la clause FROM. En fait, ils ne sont pas utilisables pour remplacer un nom d'objet (nom de table, nom de colonne, etc.).
Le seul moyen pour faire cela est d'utiliser le langage PL/pgsql.
Guillaume.
Hors ligne
#6 18/10/2008 17:46:10
- Katagoto
- Membre
Re : Fonctions variables et arguments
Ok, il est donc mieu de faire une fonction par table, ce code plante :
CREATE FUNCTION ri_ajoute_fils(IN integer, IN character) RETURNS void AS
$BODY$SELECT * FROM ri AS C WHERE C.id=$1;
UPDATE ri AS A
SET A.BordDroit = A.BordDroit + 2
WHERE A.BordDroit >= C.BordDroit;
UPDATE ri AS B
SET B.BordGauche = B.BordGauche + 2
WHERE B.BordGauche >= C.BordGauche;
INSERT INTO ri (BordDroit, BordGauche, nom) VALUES (C.BordDroit, C.BordDroit+1, $2);$BODY$
LANGUAGE 'sql' VOLATILE;
Erreur :
ERREUR: la colonne a.borddroit n'existe pas
LIGNE 5 : SET A.BordDroit = A.BordDroit + 2
^
********** Erreur **********
ERREUR: la colonne a.borddroit n'existe pas
État SQL :42703
Caractère : 151
Table :
-- Table: ri
-- DROP TABLE ri;
CREATE TABLE ri
(
id serial NOT NULL,
"BordDroit" integer,
"BordGauche" integer,
nom character(64),
CONSTRAINT ri_pkey PRIMARY KEY (id)
)
WITH (OIDS=FALSE);
ALTER TABLE ri OWNER TO katagoto;
Je comprend pas d'où ça vient...
Si quelqu'un à une idée...
Par avance merci de votre aide
Hors ligne
#7 18/10/2008 18:45:29
- gleu
- Administrateur
Re : Fonctions variables et arguments
Lire la documentation d'UPDATE semble une bonne idée pour commencer (http://docs.postgresql.fr/8.1/sql-update.html). Dans la section Paramètres, à colonne, il est indiqué :
Le nom d'une colonne dans table. Le nom de la colonne peut être qualifié avec un nom de sous-champ ou un indice de tableau, si nécessaire. Ne pas inclure le nom de la table dans la spécification d'une colonne cible -- par exemple, UPDATE tab SET tab.col = 1 est invalide.
Guillaume.
Hors ligne
#8 18/10/2008 18:59:25
- Katagoto
- Membre
Re : Fonctions variables et arguments
Même si je le met pas, ça plante...
Hors ligne
#9 21/10/2008 18:05:23
- Katagoto
- Membre
Re : Fonctions variables et arguments
Bonjour,
Je ne lâcherais rien, voilà mon code :
CREATE FUNCTION ri_ajoute_fils(IN integer, IN character) RETURNS void AS
$BODY$
UPDATE ri AS A
SET BordDroit = BordDroit + 2
FROM ri AS B
WHERE B.id = $1 AND A.BordDroit >= B.BordDroit;
UPDATE ri AS C
SET BordGauche = BordGauche + 2
FROM ri AS D
WHERE D.id = $1 AND C.BordDroit >= D.BordDroit;
INSERT INTO ri (BordDroite, BordGauche, nom)
VALUES ((SELECT BordDroite FROM ri WHERE id=$1)-2, (SELECT BordGauche FROM ri WHERE id=$1)-1, $2);
$BODY$
LANGUAGE 'sql' VOLATILE;
Ma Table :
-- Table: ri
-- DROP TABLE ri;
CREATE TABLE ri
(
id serial NOT NULL,
"BordDroit" integer,
"BordGauche" integer,
nom character(64),
CONSTRAINT ri_pkey PRIMARY KEY (id),
CONSTRAINT ri_id_key UNIQUE (id)
)
WITH (OIDS=FALSE);
ALTER TABLE ri OWNER TO katagoto;
Mon Erreur :
ERREUR: la colonne « borddroit » n'existe pas
LIGNE 4 : SET BordDroit = BordDroit + 2
^
********** Erreur **********
ERREUR: la colonne « borddroit » n'existe pas
État SQL :42703
Caractère : 112
Comment faire pour que ça marche ?
Par avance merci de votre aide
Hors ligne
#10 22/10/2008 14:41:07
- Katagoto
- Membre
Re : Fonctions variables et arguments
Voilà mon nouveau code :
CREATE FUNCTION ri_ajoute_fils(IN nomtable character, IN nom character, IN pk_parent integer) RETURNS void AS
$$
DECLARE
Bornes integer := SELECT BordDroite FROM $1 WHERE id=$3
BEGIN
UPDATE $1
SET BordDroit = BordDroit + 2
WHERE BordDroit >= Bornes;
UPDATE $1
SET BordGauche = BordGauche + 2
WHERE BordGauche >= Bornes;
INSERT INTO $1 (BordDroit, BordGauche, nom)
VALUES (Bornes, Bornes+1, $2);
END;
$$LANGUAGE 'plpgsql' VOLATILE;
Voilà mon nouveau problème :
ERREUR: erreur de syntaxe sur ou près de « SELECT »
LIGNE 1 : SELECT SELECT BordDroite FROM $1 WHERE id= $2 BEGIN UPDA...
^
REQUÊTE : SELECT SELECT BordDroite FROM $1 WHERE id= $2 BEGIN UPDATE $1 SET BordDroit = BordDroit + 2 WHERE BordDroit >= Bornes
CONTEXTE : SQL statement in PL/PgSQL function "ri_ajoute_fils" near line 6
********** Erreur **********
ERREUR: erreur de syntaxe sur ou près de « SELECT »
État SQL :42601
Contexte : SQL statement in PL/PgSQL function "ri_ajoute_fils" near line 6
Où est-ce que j'ai planté encore ?
Par avance merci de votre aide
Hors ligne
#11 23/10/2008 17:34:06
- SAS
- Membre
Re : Fonctions variables et arguments
Voilà mon nouveau code :
CREATE FUNCTION ri_ajoute_fils(IN nomtable character, IN nom character, IN pk_parent integer) RETURNS void AS
$$
DECLARE
Bornes integer := SELECT BordDroite FROM $1 WHERE id=$3
Une affectation de variable ne se fait pas de cette façon.
SELECT "BordDroite" into Bornes.
Pour commencer, je vous invite à modifier votre schéma pour supprimer la capitalisation des tables. Ca simpliefera grandement la suite.
Un certain nombre de vos erreurs viennent de problèmes entre des noms de tables à majuscules et des requêtes qui ne les utilisent pas.
Stéphane Schildknecht
Conseil, formations et support PostgreSQL
http://www.loxodata.com
Hors ligne
#12 25/10/2008 11:50:59
- Katagoto
- Membre
Re : Fonctions variables et arguments
Je pense que la casse n'est pas en cause, après la lecture du chapitre sur PL/pgsql j'arrive au code suivant :
CREATE FUNCTION ri_ajoute_fils(IN nomtable character, IN nom character, IN pk_parent integer) RETURNS void AS
$$
DECLARE
Bornes RECORD;
BEGIN
SELECT BordDroite INTO Bornes FROM nomtable WHERE id=pk_parent;
UPDATE nomtable
SET BordDroit = BordDroit + 2
WHERE BordDroit >= Bornes;
UPDATE nomtable
SET BordGauche = BordGauche + 2
WHERE BordGauche >= Bornes;
INSERT INTO nomtable (BordDroit, BordGauche, nom)
VALUES (Bornes, Bornes+1, nom);
END;
$$LANGUAGE 'plpgsql' VOLATILE;
Et donc à l'erreur suivante :
ERREUR: erreur de syntaxe sur ou près de « $1 »
LIGNE 1 : SELECT BordDroite FROM $1 WHERE id= $2
^
REQUÊTE : SELECT BordDroite FROM $1 WHERE id= $2
CONTEXTE : SQL statement in PL/PgSQL function "ri_ajoute_fils" near line 4
********** Erreur **********
ERREUR: erreur de syntaxe sur ou près de « $1 »
État SQL :42601
Contexte : SQL statement in PL/PgSQL function "ri_ajoute_fils" near line 4
Il me semblait que Pl/pgslq permettait les variable à la clause FROM, ai-je mal lu ?
Par avance merci de votre aide
Hors ligne
#13 26/10/2008 20:43:18
- Katagoto
- Membre
Re : Fonctions variables et arguments
Les paramètres de la fonction ne peuvent pas figurer au niveau de la clause FROM. En fait, ils ne sont pas utilisables pour remplacer un nom d'objet (nom de table, nom de colonne, etc.).
Le seul moyen pour faire cela est d'utiliser le langage PL/pgsql.
?
Hors ligne
#14 28/10/2008 16:22:10
- frost242
- Administrateur
Re : Fonctions variables et arguments
Et avec ça :
CREATE FUNCTION ri_ajoute_fils(IN nomtable character, IN nom character, IN pk_parent integer) RETURNS void AS
$$
DECLARE
Bornes integer;
BEGIN
EXECUTE SELECT "BordDroite" FROM nomtable WHERE id=pk_parent INTO Bornes ;
EXECUTE UPDATE nomtable
SET "BordDroit" = "BordDroit" + 2
WHERE "BordDroit" >= Bornes;
EXECUTE UPDATE nomtable
SET "BordGauche" = "BordGauche" + 2
WHERE "BordGauche" >= Bornes;
EXECUTE INSERT INTO nomtable ("BordDroit", "BordGauche", nom)
VALUES (Bornes, Bornes+1, nom);
END;
$$LANGUAGE 'plpgsql' VOLATILE;
Merci de lire le commentaire de SAS à propos de la capitalisation des noms de tables et de colonnes. PostgreSQL "minusculise" les noms des objets, sauf s'ils sont protégés par des doubles-quotes.
Thomas Reiss
Hors ligne
#15 28/10/2008 21:25:24
- Katagoto
- Membre
Re : Fonctions variables et arguments
CREATE OR REPLACE FUNCTION ri_ajoute_fils(nom_table character, nom character, pk_parent integer)
RETURNS boolean AS
$BODY$
DECLARE
Bornes RECORD;
BEGIN
EXECUTE 'SELECT BordDroite INTO Bornes FROM '|| quote_indent (nom_table)||' WHERE id=pk_parent;
UPDATE '|| quote_indent (nom_table)||'
SET BordDroit = BordDroit + 2
WHERE BordDroit >= Bornes;
UPDATE '|| quote_indent (nom_table)||'
SET BordGauche = BordGauche + 2
WHERE BordGauche >= Bornes;
INSERT INTO '|| quote_indent (nom_table)||' (BordDroit, BordGauche, nom)
VALUES (Bornes, Bornes+1, '''||nom||''');';
RETURN TRUE;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE
COST 100;
ALTER FUNCTION ri_ajoute_fils(character, character, integer) OWNER TO katagoto;
Ca marche, mais quand j'essaye de l'appeler ça plante, comment faire ?
Par avance merci de votre aide
PS : votre code n'a pas marché
Hors ligne
#16 29/10/2008 00:30:11
- frost242
- Administrateur
Re : Fonctions variables et arguments
Bien bien d'utiliser les quote_ident, mais il manque toujours les doubles-quotes (") autour des noms de colonnes contenant des lettres capitales (BordDroit par exemple).
Il manque également l'ordre EXECUTE devant les ordres UPDATE et INSERT, il est aussi nécessaire car ce sont des ordres générés dynamiquement.
En fait, il y a aussi un truc assez sympa avec PostgreSQL, c'est le debugger pas à pas PL/pgSQL: pgAdmin III le supporte depuis sa version 1.8 il me semble, et le module est fournie avec PostgreSQL 8.3 pour Windows. Sinon il est disponible à cette adresse: http://pgfoundry.org/projects/edb-debugger/.
Dernière modification par frost242 (29/10/2008 00:34:18)
Thomas Reiss
Hors ligne
#17 29/10/2008 14:55:26
- Katagoto
- Membre
Re : Fonctions variables et arguments
Ca marche mieu, du moins, ça appel ma fonction, mais il y a un bug dans ma fonction :
CREATE OR REPLACE FUNCTION ri_ajoute_fils(nom_table character, nom character, pk_parent integer)
RETURNS boolean AS
$BODY$
DECLARE
Bornes RECORD;
BEGIN
EXECUTE 'SELECT ''BordDroite'' INTO Bornes FROM '|| quote_ident (nom_table)||' WHERE id='||pk_parent||';';
EXECUTE 'UPDATE '|| quote_ident (nom_table)||'
SET ''BordDroit'' = ''BordDroit'' + 2
WHERE ''BordDroit'' >= Bornes;';
EXECUTE 'UPDATE '|| quote_ident (nom_table)||'
SET ''BordGauche'' = ''BordGauche'' + 2
WHERE ''BordGauche'' >= ''Bornes'';';
EXECUTE 'INSERT INTO '|| quote_ident (nom_table)||' (''BordDroit'', ''BordGauche'', nom)
VALUES (Bornes, Bornes+1, '''||nom||''');';
RETURN TRUE;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;
Lorsque je fais :
SELECT ri_ajoute_fils('ri', 'smart', 14);
J'ai le droit à :
ERREUR: EXECUTE of SELECT ... INTO is not implemented yet
CONTEXTE : PL/pgSQL function "ri_ajoute_fils" line 4 at EXECUTE statement********** Erreur **********
ERREUR: EXECUTE of SELECT ... INTO is not implemented yet
État SQL :0A000
Contexte : PL/pgSQL function "ri_ajoute_fils" line 4 at EXECUTE statement
Qu'est-ce que cela signifie ?
Par avance merci de votre aide
Hors ligne
#18 29/10/2008 19:20:07
- Katagoto
- Membre
Re : Fonctions variables et arguments
Pour claure le sujet :
CREATE OR REPLACE FUNCTION ri_ajoute_fils(nom_table character, nom character, pk_parent integer)
RETURNS boolean AS
$BODY$
DECLARE
Bornes RECORD;
BEGIN
EXECUTE 'SELECT "BordDroit" FROM "'|| nom_table ||'" WHERE id= ' || pk_parent || '' INTO Bornes;
EXECUTE 'UPDATE '|| quote_ident (nom_table)||'
SET "BordDroit" = "BordDroit" + 2
WHERE "BordDroit" >= '||Bornes||';';
EXECUTE 'UPDATE '|| quote_ident (nom_table)||'
SET "BordGauche" = "BordGauche" + 2
WHERE "BordGauche" >= '||Bornes||';';
EXECUTE 'INSERT INTO '|| quote_ident (nom_table)||' ("BordDroit", "BordGauche", nom)
VALUES ('||Bornes||', ('||Bornes||'+1), '''||nom||''');';
RETURN TRUE;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;
Merci à tous de votre aide
Hors ligne
#19 29/10/2008 21:38:36
- frost242
- Administrateur
Re : Fonctions variables et arguments
Chouette
Thomas Reiss
Hors ligne
Pages : 1