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
]]>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
]]>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/.
]]>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é
]]>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.
]]>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.
?
]]>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
]]>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.
]]>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
]]>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
]]>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.
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
]]>Le seul moyen pour faire cela est d'utiliser le langage PL/pgsql.
]]>