Vous n'êtes pas identifié(e).
- Contributions : Récentes | Sans réponse
Pages : 1
#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 ).
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
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
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
Pages : 1