PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

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

#1 31/12/2009 17:45:43

symphonyxrv
Membre

[RÉSOLU] libpq et result

Bonjour à tous,

je suis en train de développer un wrapper de database en C.
J'ai utilisé l'API C de MySQL et je m'attaque à celle de PG maintenant.
Sous mysql on a la possibilité de récupérer une requête de plusieurs manières :
- récupérer l'ensemble des enregistrements mysql_store_results()
- récupérer un a un les enregistrements via mysql_use_result() puis boucle sur mysql_fetch_row()

L'avantage de cette 2eme méthode et que, quand on récupère des millions d'enregistrements, on ne sature pas la RAM (pratique smile ).
Je voudrais faire la même chose avec PG.
Est-ce possible ?
J'ai vu quelque chose comme :

PQsendQuery( conn, "SELECT * FROM foo" );
res = PQgetResult(conn );
nFields = PQnfields(res);
/* Affichage des enregistrements */
for (i = 0; i < PQntuples(res); i++) {
     for (j = 0; j < nFields; j++)
            printf("%-15s", PQgetvalue(res, i, j));
}

Ce qui m'inquiète dans l'appel à PQgetvalues() c'est qu'on lui passe des index... cela veut-il dire que tout est déjà en RAM ? Le cas échéant ce n'est pas ce que je veux.
Je veux pouvoir faire des sorte de next() pour récupérer 1 à 1 les rows...

Quelqu'un peut m'aider ?

Merci d'avance smile

Hors ligne

#2 31/12/2009 18:38:21

gleu
Administrateur

Re : [RÉSOLU] libpq et result

L'utilisation d'un curseur permet cela. Voir http://docs.postgresql.fr/8.4/sql-fetch.html pour les détails.


Guillaume.

Hors ligne

#3 11/01/2010 17:27:56

symphonyxrv
Membre

Re : [RÉSOLU] libpq et result

Merci beaucoup Gleu pour ta réponse.
J'ai regardé les curseurs et en effet cela semble correspondre à mes besoins smile
Néanmoins cela veut-il dire que PQsendQuery monte tous les enregistrements en RAM ?

Cordialement,

Hors ligne

#4 11/01/2010 17:42:16

Marc Cousin
Membre

Re : [RÉSOLU] libpq et result

Non, PQsendQuery soumet seulement la requête au serveur. C'est ensuite à vous d'aller récupérer les enregistrements via PQgetResult.
Vous aurez, si vous passez par le mécanisme du curseur, plusieurs ordres SQL à passer :
- création du curseur (DECLARE)
- FETCH en boucle (un par un ou plusieurs à la fois, on peut faire un fetch 100 par exemple, sachant que dans ce cas vous utiliserez de la mémoire pour stocker ces 100 enregistrements côté client)
- destruction du curseur (CLOSE)

À chaque fois, il faudra un PQSendQuery, un (deux en fait pour avoir celui qui retourne null) (ou plusieurs si vous faites FETCH 100) PQgetResult.

Dernière modification par Marc Cousin (11/01/2010 17:44:02)


Marc.

Hors ligne

#5 11/01/2010 18:09:46

symphonyxrv
Membre

Re : [RÉSOLU] libpq et result

Merci Marc pour cette réponse.
Je me suis trompé lors de mon précédent mail.
Je voulais mettre : PQgetResult au lieu de PQsendQuery.
La phrase corrigée est donc : Néanmoins cela veut-il dire que PQgetResult monte tous les enregistrements en RAM ?
Le cas échéant, je n'ai donc aucune autre possibilité que de passer par des curseurs pour gérer un mode 'lazy' pour récupérer les données ?

Cordialement,

Hors ligne

#6 11/01/2010 18:40:06

Marc Cousin
Membre

Re : [RÉSOLU] libpq et result

PQgetResult monte tous les enregistrements en RAM. D'où l'utilisation de fetch, qui fait que PQgetResult monte tous les enregitrements que lui a retourné l'ordre fetch en ram, soit 1 si vous ne précisez rien, ou la valeur que vous précisez à fetch (100 dans mon exemple). Sachant qu'il est intéressant de récupérer plusieurs enregistrements à la fois, pour des raisons de performance (moins de dialogues entre le client et le serveur).

Pour ne récupérer les enregistrements qu'au fur et à mesure, vous devez passer par un curseur (ou bien faire des ordres SQL renvoyant moins de résultat, en utilisant limit et offset)


Marc.

Hors ligne

#7 12/01/2010 12:39:26

symphonyxrv
Membre

Re : [RÉSOLU] libpq et result

Merci Marc pour ces précisions, cela m'a grandement aidé.

Cordialement,

Hors ligne

Pied de page des forums