2009-06-04 7 views
3

Je voudrais regrouper plusieurs requêtes dans une seule fonction qui réside dans PostgreSQL. La fonction sera interrogée à l'aide de PDO.Pouvez-vous retourner plusieurs ensembles de résultats en utilisant PDO et PostgreSQL?

La fonction est:

CREATE OR REPLACE FUNCTION "test_multipe_refcursor"() 
RETURNS SETOF refcursor AS $BODY$ 

DECLARE 
    parentRC refcursor; 
    childRC refcursor; 

BEGIN 

open parentRC FOR 
SELECT * FROM parent; 
RETURN NEXT parentRC; 

open childRC FOR 
SELECT * FROM child; 
RETURN NEXT childRC; 

RETURN; 

END;$BODY$ 
LANGUAGE 'plpgsql' VOLATILE; 

ALTER FUNCTION "test_multipe_refcursor"() OWNER TO postgres; 

Voici le code PHP. "Database" en tant que classe singleton qui configure les propriétés de connexion habituelles, rien de spécial.

$database = Database::load(); 
    $sql = "select * from test_multipe_refcursor();"; 
    $p = $database->query($sql); 

    $i = 1; 
    do 
    { 
    $this->set('set' . $i, $p->fetchAll(PDO::FETCH_ASSOC)); 
    $i++; 
    } while ($p->nextRowset()); 

    $p->closeCursor(); 

Et le résultat.

PDOException: SQLSTATE[IM001]: Driver does not support this function: driver does not support multiple rowsets in xxxx.php on line 32 

Ceci semblerait indiquer que ce n'est pas supporté, mais encore une fois, je ne trouve pas de liste définissant exactement ce qui est.

Est-ce que quelqu'un a réussi à obtenir ce fonctionnement?

Références:

Répondre

4

Prise en charge de retour est encore plusieurs resultsets sur la PostgreSQL todo list et il frappera certainement pas 8,4. En ce qui concerne la méthode setof refcursors, ce que vous essayez de faire ne fonctionne pas car la fonction ne retourne pas plusieurs ensembles de lignes - elle retourne un ensemble de lignes de refcursors. Je ne suis pas sûr si l'utilisation de refcursors côté client fonctionne, mais je ne le trouve pas probable, même si le protocole client-serveur le prend en charge, il est peu probable que PDO ait une API pour cela.

Mais pourquoi essayez-vous de renvoyer plusieurs ensembles de résultats dans une requête? Vous pouvez toujours faire les requêtes séparément.

+0

C'est pour un processus de planification plutôt compliqué, renvoyant plusieurs tables parent et enfant en conséquence. Plusieurs requêtes partagent des paramètres et ce serait plus rapide sur la base de données, plus je voudrais les regrouper pour faciliter la maintenance et réduire les allers-retours. Et bien.. –

1

Près du bas de this PostgreSQL doc page, il y a une section décrivant comment vous pouvez renvoyer un ou plusieurs curseurs d'une fonction. Fondamentalement, vous obtenez l'appelant pour indiquer le nom du curseur (s) en tant que paramètres:

CREATE FUNCTION myfunc(refcursor, refcursor) RETURNS SETOF refcursor AS $$ 
BEGIN 
    OPEN $1 FOR SELECT * FROM table_1; 
    RETURN NEXT $1; 
    OPEN $2 FOR SELECT * FROM table_2; 
    RETURN NEXT $2; 
END; 
$$ LANGUAGE plpgsql; 

-- need to be in a transaction to use cursors. 
BEGIN; 

SELECT * FROM myfunc('a', 'b'); 

FETCH ALL FROM a; 
FETCH ALL FROM b; 
COMMIT; 

La page est pour PostgreSQL 8.4, mais cet extrait de la documentation est présente au moins aussi loin que 8.1 (la version I Je cours). Comme le dit le commentaire, vous devez être dans une transaction pour utiliser les curseurs, car ils sont implicitement fermés à la fin de chaque transaction (c'est-à-dire à la fin de chaque déclaration si le mode autocommit est activé).