1

PostgreSQL データベースにアクセスできるプログラムを作成しようとしています。問題は、私が取得し続けることです

警告: すでに進行中のトランザクションがあります

メッセージが表示され、プログラムはすぐに終了します。必要に応じて接続を閉じて再度開く必要がありますか? それとも、問題を修正してプログラム全体で同じ接続を再利用できますか?

    int i = 0;
    std::string spassw = "";
    std::string suname = "";

    theconn = NULL;

    // Make a connection to the database
    theconn = PQconnectdb("user=postgres password=changeme dbname=database hostaddr=127.0.0.1    port=5432");

    // Check to see that the backend connection was successfully made
    if ( PQstatus(theconn) != CONNECTION_OK )   {

        std::cout << "Connection to database failed.\nPress any key to continue.\n";
        PQfinish(theconn);
        getchar();
        exit(1);
     }

    PGresult *res  = PQexec(theconn, "BEGIN");

    if (PQresultStatus(res) != PGRES_COMMAND_OK)    {

        printf("BEGIN command failed");
        PQclear(res);
        PQfinish(theconn);
        std::cout << "Goodbye.\n";
        getchar();
        exit(1);
    }

    // Clear result
    PQclear(res);

    res = PQexec(theconn, "DECLARE emprec CURSOR FOR select * from dbtable");

    if (PQresultStatus(res) != PGRES_COMMAND_OK)    {

        printf("DECLARE CURSOR failed\n");
        PQclear(res);
        PQfinish(theconn);
        std::cout << "Goodbye.\n";
        getchar();
        exit(1);
     }

    PQclear(res);
    res = PQexec(theconn, "FETCH ALL in emprec");

    if (PQresultStatus(res) != PGRES_TUPLES_OK) {

        printf("FETCH ALL failed");
        PQclear(res);
        PQfinish(theconn);
        std::cout << "Goodbye.\n";
        getchar();
        exit(1);
    }

    for ( i = 0; i < PQntuples(res); i++ )    {

        std::string suname = PQgetvalue( res, i, 0 );
        std::string spassw = PQgetvalue( res, i, 1 );

        if( pname == suname && pword == spassw )    {

        res = PQexec( theconn, "COMMIT");
        PQclear(res);

        res = PQexec(theconn, "CLOSE emprec" );
        PQclear(res);

        // End the transaction
        res = PQexec(theconn, "END");

        // Clear result
        PQclear(res);
        return true;
        }

    }

    res = PQexec( theconn, "COMMIT");
        PQclear(res);

    res = PQexec(theconn, "CLOSE emprec");
    PQclear(res);

    // End the transaction
    res = PQexec(theconn, "END");

    // Clear result
    PQclear(res);


    return false;
}
4

2 に答える 2

0

コードにはトランザクションを開始する があるため、一致する、 またはがBEGIN1 つだけある必要がありますが、両方は必要ありません。COMMITEND

その理由はEND、実際には の同義語だからですCOMMIT。これについて、マニュアルには次のように書かれています。

このコマンドは、COMMIT と同等の PostgreSQL 拡張機能です。

カーソルを閉じると、コードが現在どのように編成されているかを考えると、次のことが発生します。

   res = PQexec( theconn, "COMMIT");
        PQclear(res);

削除するだけです。

于 2013-01-04T15:29:12.570 に答える