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 25/11/2008 13:58:17

elekis
Membre

PQexecPrepared : le curseur myportal existe deja

bonjour, je remet mon message ici en esperant avoir un peu plus de chanse

voila, j'essaie de faire un simple petit programme avec des cursors et des variables dynamique (les $X) en C. le but etant que j'arrive a changer la variable sans refaire le prepare .

je fait donc 

 PQprepare  (conn,
                       "my_cursor",
                       "DECLARE myportal CURSOR FOR select * from tab_3 WHERE COL_3 = $1",
                       1,       /* one param */
                       NULL);

une seul fois
et puis je fais un

  paramValues[0]= "zzze";
    res = PQexecPrepared(conn,
                         "my_cursor",
                         1,
                         paramValues,
                         NULL,
                         NULL,
                         1);

ensuite je fetch (tout fonctionne)
et puis ben j'aimerais bien changer la valeur du param
je fais donc un

    paramValues[0]= "ee";
    res = PQexecPrepared(conn,
                       "my_cursor",
                        1,
                        paramValues,
                        NULL,
                        NULL,
                        1);

et la cela foire. j'ai le message
ERREUR:  le curseur ½ myportal ╗ existe dÚjÓ
or je sais qu'il existe, c'est le but big_smile.

qqn aurait il une idée de pourquoi??? et comment resoudre

merci a++

voici le code complet (basé sur un example)

/*
 * testlibpq.c
 *
 *      Test the C version of libpq, the PostgreSQL frontend library.
 */
#include <stdio.h>
#include <stdlib.h>
#include "libpq-fe.h"

static void
exit_nicely(PGconn *conn)
{
    PQfinish(conn);
    exit(1);
}

PGresult* FetchFirst(PGconn * conn){
    PGresult* res = PQexec(conn, "FETCH FIRST in myportal");
    if (PQresultStatus(res) != PGRES_TUPLES_OK)
    {
        fprintf(stderr, "FETCH  failed: %s", PQerrorMessage(conn));
        PQclear(res);
        exit_nicely(conn);
    }
    return res;
}


int
main(int argc, char **argv)
{

    PGconn     *conn;
    PGresult   *res;
    int         nFields;
    int         i,
                j;
    const char *paramValues[1];


    conn = PQsetdbLogin("localhost", NULL, NULL,NULL, "dbu", "root","ouvretoi");

    if (PQstatus(conn) != CONNECTION_OK)
    {
        fprintf(stderr, "Connection to database failed: %s",
                PQerrorMessage(conn));
        exit_nicely(conn);
    }

    res = PQexec(conn, "BEGIN");
    if (PQresultStatus(res) != PGRES_COMMAND_OK)
    {
        fprintf(stderr, "BEGIN command failed: %s", PQerrorMessage(conn));
        PQclear(res);
        exit_nicely(conn);
    }
     PQclear(res);
     res =  PQprepare  (conn,
                       "my_cursor",
                       "DECLARE myportal CURSOR FOR select * from tab_3 WHERE COL_3 = $1",
                       1,       /* one param */
                       NULL); 

    PQclear(res);

    paramValues[0]= "zzze";
    res = PQexecPrepared(conn,
                         "my_cursor",
                         1,
                         paramValues,
                         NULL,
                         NULL,
                         1);

    if (PQresultStatus(res) != PGRES_COMMAND_OK)
    {
        fprintf(stderr, "DECLARE CURSOR failed: %s", PQerrorMessage(conn));
        PQclear(res);
        exit_nicely(conn);
    }
    PQclear(res);


    res = FetchFirst(conn);

    nFields = PQnfields(res);
    for (i = 0; i < nFields; i++)
        printf("%-15s", PQfname(res, i));
    printf("\n\n");

    while(PQresultStatus(res) == PGRES_TUPLES_OK && PQntuples(res) == 1)
    {
            for (j = 0; j < nFields; j++)
                printf("%-15s", PQgetvalue(res, 0, j));
            printf("\n");
            PQclear(res);
            res = PQexec(conn, "FETCH NEXT in myportal");
    }
    PQclear(res);


    paramValues[0]= "ee";
    res = PQexecPrepared(conn,
                       "my_cursor",
                        1,
                        paramValues,
                        NULL,
                        NULL,
                        1);

    fprintf(stderr, " %s", PQerrorMessage(conn));
    res = FetchFirst(conn);


    /* first, print out the attribute names */
    nFields = PQnfields(res);
    for (i = 0; i < nFields; i++)
        printf("%-15s", PQfname(res, i));
    printf("\n\n");

    while(PQresultStatus(res) == PGRES_TUPLES_OK && PQntuples(res) == 1)
    {
            for (j = 0; j < nFields; j++)
                printf("%-15s", PQgetvalue(res, 0, j));
            printf("\n");
            PQclear(res);
       res = PQexec(conn, "FETCH NEXT in myportal");
    }
    PQclear(res);


    res = PQexec(conn, "CLOSE myportal");
    PQclear(res);

    /* end the transaction */
    res = PQexec(conn, "END");
    PQclear(res);

    /* close the connection to the database and cleanup */
    PQfinish(conn);

    return 0;
}

Hors ligne

#2 27/11/2008 15:02:43

elekis
Membre

Re : PQexecPrepared : le curseur myportal existe deja

c'est bon, j'ai trouve, il faut faire un close cursor

a++

Hors ligne

#3 27/11/2008 15:11:05

gleu
Administrateur

Re : PQexecPrepared : le curseur myportal existe deja

J'avoue que je ne comprends pas bien le PQprepare que tu fais. J'aurais plutôt fait ceci :

PQprepare  (conn,
                       "my_cursor",
                       "select * from tab_3 WHERE COL_3 = $1",
                       1,       /* one param */
                       NULL);

Parce que, en fait, PostgreSQL ne se plaint pas que le curseur est déjà défini. Il se plaint que le portail est déjà défini. Donc soit tu fermes en premier lieu le curseur, soit tu n'utilises pas de portail (qui n'est pas utile à ma connaissance pour faire ce que tu fais).


Guillaume.

Hors ligne

#4 28/11/2008 11:55:11

elekis
Membre

Re : PQexecPrepared : le curseur myportal existe deja

en fait, j'ai du faire ceci

   res =  PQprepare  (conn,
                                 "cursor_name",
                                 "DECLARE select_cursor CURSOR WITH HOLD FOR select * from tab_3 WHERE col_3 = $1",
                                 1,       /* one param */
                                 NULL);

le truc, c'est que dans l'application reel, le open et le fetch sont appelé via des progrma (au sens cobol) different.  et donc je ne sais pas faire de begin end ( car je ne saurais pas quand faire le end)

merci pour ntout

a++

Hors ligne

Pied de page des forums