Précédent   Forum des professionnels en informatique > PHP > PHP & SGBD > PHP & PostgreSQL
PHP & PostgreSQL Forum d'entraide sur PostgreSQL avec PHP. Avant de poster -> FAQ PostgreSQL, Cours PostgreSQL. Pour les questions concernant le moteur PostgreSQL plutôt que les fonctions PHP, merci d'utiliser le forum PostgreSQL.
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 18/08/2011, 20h40   #1
Expert Confirmé
 
Avatar de rawsrc
 
Homme Martin
Dev indep
Inscription : mars 2004
Messages : 1 461
Détails du profil
Informations personnelles :
Nom : Homme Martin
Âge : 35
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Dev indep

Informations forums :
Inscription : mars 2004
Messages : 1 461
Points : 2 551
Points : 2 551
Envoyer un message via Skype™ à rawsrc
Par défaut PDO avec le format tableau de postgre ARRAY[]

Bonjour,

Je me bats avec PDOStatement pour exécuter un appel d'une fonction stockée qui attend deux tableaux en paramètre. Bref, rien de sorcier à première vue. Le hic, c'est que j'ai beau tout tordre dans tous les sens, je récupère toujours un message d'erreur.

Voici, la fonction stockée :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
CREATE OR REPLACE FUNCTION public.tempadd (
  num_att integer [],
  vals varchar []
)
RETURNS pg_catalog.void AS
$body$
BEGIN  
   FOR i IN 1..2 LOOP
      INSERT INTO t_temp ("numAttr", "valeur")
      VALUES (num_att[i]::INTEGER, vals[i]::VARCHAR);
   END LOOP;
END;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY DEFINER
COST 100;
Cette fonction attend 2 paramètres tableaux : un tableau d'integer et un tableau de string.

Voici une des syntaxes qui passe (montée manuellement) avec PDOStatement :
Code :
$sql = 'SELECT public.tempadd(ARRAY[50, 51], ARRAY[$$abc$$, $$def$$]);';
Ensuite j'ai essayé de passer ceci :
Code :
$sql = 'SELECT public.tempadd(ARRAY[:n1, :n2], ARRAY[:v1, :v2]);';
On prépare la requête, on attache les valeurs aux paramètres du statement (bindValue ou bindParam, les 2 aucune erreur) et on fait un et là boum erreur :
Code :
SQLSTATE[42883]: Undefined function: 7 ERREUR: la fonction public.tempadd(text[], text[]) n'existe pas LINE 1: SELECT public.tempadd(ARRAY[$1, $2], ARRAY[$3, $4]);
J'ai beau tourner dans tous les sens, il me semble impossible de faire autrement qu'en montant soit même la chaine sql.

Si vous êtes arrivé à contourner ce problème en utilisant PDOStatement, je suis preneur de l'astuce.
Merci
__________________
# Dans la Création, tout est permis mais tout n'est pas utile...
rawsrc est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/08/2011, 08h14   #2
Expert Confirmé
 
Avatar de rawsrc
 
Homme Martin
Dev indep
Inscription : mars 2004
Messages : 1 461
Détails du profil
Informations personnelles :
Nom : Homme Martin
Âge : 35
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Dev indep

Informations forums :
Inscription : mars 2004
Messages : 1 461
Points : 2 551
Points : 2 551
Envoyer un message via Skype™ à rawsrc
Allez je vais me répondre comme ça je ne devrai pas être trop déçu de la reponse

Ce qui suit est valable pour PHP 5.3.6 et inférieur

Après un paquet d'essais, cela n'a jamais fonctionné.
Donc en conclusion, quand vous utilisez les tableaux postgre pour le passage de vos arguments il faut monter manuellement toute la chaine SQL, protéger vous-même vos valeurs et l'exécuter directement sans la case prepare()
Ne vous amusez pas à juste mettre à plat le tableau et conserver d'autre tags car il y a un très gros piège :
Ex :
Code :
$sql = 'SELECT public.tempadd(:nom, ARRAY[50, 51], ARRAY[$$abc$$, $$def$$]);';
Cette requête passe la préparation sans problème mais si maintenant vous avez dans votre tableau une valeur qui contient un texte avec deux-points :
Code :
$sql = 'SELECT public.tempadd(:nom, ARRAY[50, 51], ARRAY[$$abc$$, $$ceque:vousvoulez$$]);';
vous remarquerez que PDO::prepare() va reconnaitre un tag inattendu : A l'exécution vous vous rendrez-compte que tous vos petits n'y seront pas.

Je vous mets ci-dessous, la fonction de protection des textes avec la notation (très pratique au passage) de postgre :
Code :
1
2
3
4
5
6
7
8
function escapeStringForPostgre($p) {
   # on vérifie s'il y aurait besoin de changer de délimiteur sous postgre (sensible à la casse)
   $delim = '$$';
   while(FALSE !== mb_strpos($p, $delim)) {
      $delim = '$hkyz' . mt_rand(10000, 99999) . 'qyvx$';
   }
   return $delim . $p . $delim;   
}
Allez c'est résolu
__________________
# Dans la Création, tout est permis mais tout n'est pas utile...
rawsrc est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 16h22.


 
 
 
 
Partenaires

Hébergement Web