Vous n'êtes pas identifié(e).

#1 02/03/2010 10:53:36

mortimer.pw
Membre

REFCURSOR et PHP

Bonjour à tous,

Je travaille sous Cent-OS 5.2, PostgreSQL 8.4.2.
Je souhaite récupérer un REFCURSOR dans un tableau sous PHP (grand débutant PHP).

J'ai écrit une Fonction Postgres qui retourne un REFCURSOR.

CREATE OR REPLACE FUNCTION USER.Clients() RETURNS REFCURSOR AS '
DECLARE
        RClient REFCURSOR;
BEGIN
        OPEN RClient FOR
                SELECT C.id_client,C.libelle
                FROM USER.Client C;
        RETURN RClient;
END;
' LANGUAGE 'plpgsql';

J'ai utilisé PG_FETCH_ARRAY sous PHP (comme dans la Doc : http://www.php.net/manual/fr/function.p … array.php).
J'essaye d'afficher les valeurs mais je n'obtiens rien.

        public function db_ref_cursor($_query)
        {
                $aRetTab = array();
                $result = pg_query($_query);
                while ($arr = pg_fetch_array($result,NULL,PGSQL_ASSOC))
                        {
                                echo $arr["libelle"].' <br/> <br/>';
                        }
                pg_free_result($result);
                return $aRetTab;
        }

Quelqu'un à t'il déjà utilisé un REFCURSOR sous PHP ?

Pouvez-vous m'aider à construire mon tableau à partir de ce REFCURSOR ?

Merci pour les réponses.

Hors ligne

#2 02/03/2010 12:08:22

gleu
Administrateur

Re : REFCURSOR et PHP

Pourquoi voulez-vous utiliser un refcursor ? PHP ne sait pas les gérer, il faudra exécuter d'autres ordres SQL pour récupérer les données du refcursor.


Guillaume.

Hors ligne

#3 02/03/2010 12:20:26

mortimer.pw
Membre

Re : REFCURSOR et PHP

Bonjour Guillaume,

En fait, je dois reprendre une interface écrite en PHP.

Cette interface communiquait avec une BD Oracle.
Je dois l'adapter pour communiquer avec PostgreSQL.

J'ai des fonctions Oracle qui renvoient des SYS_REFCURSOR.
J'ai réécrit pour renvoyer des REFCURSOR.

Je dois maintenant les exploiter dans le PHP.

Y-a-t'il une solution ?

Merci pour ton aide.

Hors ligne

#4 02/03/2010 12:37:07

gleu
Administrateur

Re : REFCURSOR et PHP

Oui, il y a plusieurs solutions. Mais s'il faut conserver les refcursor, vous devrez passer par des appels aux instructions SQL comme FETCH (http://docs.postgresql.fr/8.4/sql-fetch.html) et MOVE (http://docs.postgresql.fr/8.4/sql-move.html). Vous avez quelques exemples sur http://docs.postgresqlfr.org/8.4/plpgsql-cursors.html .


Guillaume.

Hors ligne

#5 02/03/2010 12:59:57

mortimer.pw
Membre

Re : REFCURSOR et PHP

Guillaume,

J'ai bien compris le principe PostgreSQL.

Par contre côté PHP, cela veut-il dire que $result = pg_query($_query); me retourne le nom du curseur ?
Et que je dois faire un nouveau query : $result2 = pg_query("FETCH ALL IN ".$result); ?
Avant de faire la boucle : while ($arr = pg_fetch_array($result2,NULL,PGSQL_ASSOC)) ?

Je ne connais vraiment pas PHP et n'est pas trouvé d'exemple.

Merci pour les solutions.

Hors ligne

#6 02/03/2010 13:03:49

gleu
Administrateur

Re : REFCURSOR et PHP

Et que je dois faire un nouveau query : $result2 = pg_query("FETCH ALL IN ".$result); ?

Non, pas de $result. $result est un pointeur vers le résultat. Il faut faire un appel à pg_fetch_array par exemple pour récupérer la première colonne de la seule ligne, et envoyer l'information de cette première colonne à la place de $result dans le deuxième pg_query. Autrement dit, quelque chose comme ça :

$result = pg_query($_query);
$arr = pg_fetch_array($result,NULL,PGSQL_ASSOC);
$result2 = pg_query("FETCH ALL IN ".$arr[0]);

À remanier amplement, mais c'est l'idée de base.


Guillaume.

Hors ligne

#7 02/03/2010 14:58:25

mortimer.pw
Membre

Re : REFCURSOR et PHP

Désolé Guillaume, mais il semble que le tableau soit vide.

Voici les lignes de PHP :
                $result1 = pg_query($_query);
                $arr1 = pg_fetch_array($result1,NULL,PGSQL_ASSOC);
                $tmp = array_keys($arr1);
                $result2 = pg_query("FETCH ALL IN ".$tmp[0]);
                $arr2 = pg_fetch_array($result2,NULL,PGSQL_ASSOC);

voici ce qui s'affiche :
Warning: pg_query() [function.pg-query]: Query failed: ERROR: cursor "data" does not exist in /usr/local/apache....
Warning: pg_fetch_array() expects parameter 1 to be resource, boolean given in /usr/local/apache....

J'ai ajouté : print_r("--".$_query."--");  pour voir la query, et j'obtiens cela :
--select User.Clients() as data --

Peux-tu m'aider ?

Dernière modification par mortimer.pw (03/03/2010 09:23:54)

Hors ligne

#8 03/03/2010 15:46:07

mortimer.pw
Membre

Re : REFCURSOR et PHP

Si cela peut aider d'autres personnes :

function test_refcursor()
{
  pg_query("begin");
  $res1 = pg_query("SELECT fcurs()");
  if ($res1!==false) {
    list($cname) = pg_fetch_array($res1);
    $res2 = pg_query("FETCH ALL IN \"" . $cname . "\"");
    if ($res2!==false) {
      $all = pg_fetch_all($res2);
      print_r($all);
    }
  }
  pg_query("commit");
}

Solution proposée par Estofilo sur Developpez.com

Hors ligne

#9 03/03/2010 20:48:33

gleu
Administrateur

Re : REFCURSOR et PHP

Oui, un curseur n'est valide que dans une transaction.


Guillaume.

Hors ligne

Pied de page des forums