Postgres Async API检测查询结束

Jus*_*wer 6 c sql postgresql asynchronous

我正在使用PostgreSQL C API.阅读文档时,它指出当PQgetResult返回NULL时,查询结束,如果PQisBusy没有返回0,PQgetResult将阻塞.但是如果没有更多输入,PQisBusy返回1,所以我不能调用PQgetResult并获得NULL.因此我不知道查询是否结束.有没有其他方法可以知道查询是否完成?我误解了异步API吗?

- - 编辑 - - -

C代码的基本思想是:

PQsendQuery(conn, query)

while(true)
{
    PQconsumeInput(conn)
    if(PQisBusy(conn) == 0)
    {
        PGresult* res = PQgetResult(conn);
        if(res)
        {
            //print result
        }
        else
        {
            //res == NULL
            //indicates query is over
            break;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

结果将被打印,但循环永远不会终止.因为PQisBusy只返回0一次.

whu*_*nmr 5

我认为你需要的是PQsetSingleRowModePQgetResult每次返回一行。

来自http://www.postgresql.org/docs/9.2/static/libpq-single-row-mode.html

通常,libpq 收集 SQL 命令的整个结果并将其作为单个 PGresult 返回到应用程序。对于返回大量行的命令来说,这可能行不通。对于这种情况,应用程序可以在单行模式下使用 PQsendQuery 和 PQgetResult。在此模式下,结果行一次返回给应用程序,就像从服务器接收到的结果行一样。

如果查询返回任何行,它们将作为单独的 PGresult 对象返回,除了状态代码为 PGRES_SINGLE_TUPLE 而不是 PGRES_TUPLES_OK 之外,它们看起来与正常查询结果类似。在最后一行之后,或者如果查询返回零行,则立即返回状态为 PGRES_TUPLES_OK 的零行对象;这是不再有行到达的信号。

查看示例代码: https://github.com/markokr/libpq-rowproc-demos/blob/master/demo-onerow-async.c


Muh*_*ama 0

我可以看到代码有一个问题,您没有检查 PQconsumeInput(conn) 函数的返回。因为清除忙碌标志是 PQconsumeInput 的责任。可能发生的情况是 PQconsumeInput 将在不处理任何数据并清除繁忙标志的情况下失败。

我认为在调用 PQisBusy 之前检查 PQconsumeInput 的结果应该可以正常工作。

while (PQconsumeInput(conn) == 1) 
{
  if(PQisBusy(conn) == 0)
  {
        PGresult* res = PQgetResult(conn);
        if(res)
        {
            //print result
        }
        else
        {
            //res == NULL
            //indicates query is over
            break;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)