Vous n'êtes pas identifié(e).
- Contributions : Récentes | Sans réponse
#1 20/07/2009 13:08:37
- zied
- Membre
Passer le nom d'un Champ comme paramètre d'une proc. stockée
Bonjour
Je veux créer une procédure stocké à laquelle je veux passer en paramètre 2 variables Le nom d'un champ et sa valeur
J'ai écrit ce code pour tester mais ça ne marche pas :
CREATE OR REPLACE FUNCTION __searchtest(character, character)
RETURNS SETOF record AS
$BODY$
select prod_version from vprod_details
where $1=$2;
$BODY$
LANGUAGE 'sql' VOLATILE
COST 100
ROWS 1000;
ALTER FUNCTION __searchtest(character, character) OWNER TO postgres;
avec $1 le nom du champ et $2 est la valeur du champ.
Est-ce possible?
Si oui comment faire?
Hors ligne
#2 20/07/2009 14:19:11
- Marc Cousin
- Membre
Re : Passer le nom d'un Champ comme paramètre d'une proc. stockée
Impossible de le faire de la sorte : la fonction sql ne peut pas avoir comme variable le nom d'une colonne je pense.
Il faudra passer par du plpgsql et fabriquer l'ordre SQL à la volée, comme expliqué ici :
http://docs.postgresql.fr/8.4/plpgsql-statements.html paragraphe 38.5.4.
Evidemment, cela aussi est pénible, puisqu'il faut fabriquer l'ordre SQL par concaténation
Marc.
Hors ligne
#3 20/07/2009 15:57:09
- zied
- Membre
Re : Passer le nom d'un Champ comme paramètre d'une proc. stockée
J'ai essayé cette écriture
CREATE OR REPLACE FUNCTION __searchtest2(character, character)
RETURNS bigint AS
$BODY$
PREPARE test(character,character) AS SELECT prod_version FROM vprod_details
WHERE $1=$2;
EXECUTE test('prod_ref','ZA01820C');
$BODY$
LANGUAGE 'sql' VOLATILE
COST 100;
ALTER FUNCTION __searchtest(character, character) OWNER TO postgres;
J'ai l'erreur suivante
ERROR: return type mismatch in function declared to return bigint
DÉTAIL : Function's final statement must be a SELECT.
CONTEXTE : SQL function "__searchtest2"
Hors ligne
#4 20/07/2009 16:47:41
- gleu
- Administrateur
Re : Passer le nom d'un Champ comme paramètre d'une proc. stockée
Vous ne pouvez pas le faire en SQL. Il faut obligatoirement passer par PL/pgsql (ou un autre, plus évolué que SQL).
CREATE OR REPLACE FUNCTION __searchtest2(character, character)
RETURNS bigint AS
$BODY$
DECLARE
requete text;
ma_valeur le_type_de_ma_valeur;
BEGIN
requete := 'SELECT prod_version FROM vprod_details WHERE '||quote_ident($1)||'='||quote_literal($2);
EXECUTE requete INTO mavaleur;
RETURN ma_valeur;
END
$BODY$
LANGUAGE 'plpgsql';
Quelque chose comme cela me paraît mieux. Il y a certainement moyen de mieux faire avec les dernières versions de PostgreSQL (notamment avec la 8.4 et son RETURN QUERY EXECUTE).
Guillaume.
Hors ligne
#5 21/07/2009 11:00:13
- zied
- Membre
Re : Passer le nom d'un Champ comme paramètre d'une proc. stockée
Merci.
Voici le résultat final
CREATE OR REPLACE FUNCTION __searchtest3
(
_key character varying,
_value character varying,
OUT prod_version bigint
)
RETURNS bigint
AS $$
DECLARE __query text DEFAULT NULL;
BEGIN
__query := 'SELECT prod_version FROM vprod_details WHERE "' || _key || '" = \'' || _value || '\'';
EXECUTE __query INTO prod_version;
RETURN;
END $$ LANGUAGE plpgsql;
Hors ligne
#6 21/07/2009 11:50:37
- gleu
- Administrateur
Re : Passer le nom d'un Champ comme paramètre d'une proc. stockée
N'oubliez pas quote_literal. Ça vous protège des chaînes contenant par exemple des guillemets. Car là, avec votre code, si _value contient un guillemet, la fonction échouera. Sans compter que ça permet une attaque de type injection SQL du plus mauvais effet.
Guillaume.
Hors ligne
#7 21/07/2009 12:03:08
- zied
- Membre
Re : Passer le nom d'un Champ comme paramètre d'une proc. stockée
Merci gleu.
C'est un détail qui m'a échappé
Hors ligne