受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发版本: devel

32.6. 分块检索查询结果 #

通常,libpq会收集一条 SQL 命令的完整结果,并将其作为单个PGresult返回给应用程序。对于返回大量行的命令,这可能并不适用。对于这类情况,应用程序可以将PQsendQueryPQgetResult用于单行模式分块模式。在这些模式下,结果行会在从服务器收到时立即返回给应用程序;单行模式每次返回一行,分块模式则每次返回一组行。

要进入这些模式之一,请在成功调用PQsendQuery(或其兄弟函数)后立即调用PQsetSingleRowModePQsetChunkedRowsMode。这种模式选择只对当前正在执行的查询生效。然后按Section 32.4所述,反复调用PQgetResult直到其返回空指针。如果查询返回了任何行,这些行会作为一个或多个PGresult对象返回。它们看起来与普通查询结果相同,只是状态码在单行模式下为PGRES_SINGLE_TUPLE,在分块模式下为PGRES_TUPLES_CHUNK,而不是PGRES_TUPLES_OK。每个PGRES_SINGLE_TUPLE对象恰好包含一行结果,而PGRES_TUPLES_CHUNK对象至少包含一行、至多包含指定的每块行数。最后一行之后,或者如果查询返回零行,则会返回一个状态为PGRES_TUPLES_OK且不含行的对象,表示不会再有更多行到达。(但请注意,仍然必须继续调用PQgetResult直到其返回空指针。)所有这些PGresult对象都会包含与普通查询结果相同的行描述数据(列名、类型等)。每个对象在使用完之后都应像往常一样通过PQclear释放。

在使用管道模式时,必须在用PQgetResult提取该查询结果之前,为管道中的每个查询分别激活单行模式或分块模式。更多信息见Section 32.5

PQsetSingleRowMode #

为当前正在执行的查询选择单行模式。

int PQsetSingleRowMode(PGconn *conn);

此函数只能在调用PQsendQuery或其某个兄弟函数之后立即调用,并且必须在该连接上执行任何其他操作之前调用,例如PQconsumeInputPQgetResult。如果调用时机正确,该函数会为当前查询激活单行模式并返回 1;否则模式保持不变并返回 0。无论如何,当前查询结束后都会恢复为普通模式。

PQsetChunkedRowsMode #

为当前正在执行的查询选择分块模式。

int PQsetChunkedRowsMode(PGconn *conn, int chunkSize);

该函数与PQsetSingleRowMode类似,不同之处在于它指定每个PGresult最多返回chunkSize行,而不一定只返回一行。此函数也只能在调用PQsendQuery或其某个兄弟函数之后立即调用,并且必须在该连接上执行任何其他操作之前调用,例如PQconsumeInputPQgetResult。如果调用时机正确,该函数会为当前查询激活分块模式并返回 1;否则模式保持不变并返回 0。无论如何,当前查询结束后都会恢复为普通模式。

Caution

在处理一个查询的过程中,服务器可能先返回一些行,然后遇到错误并中止该查询。通常,libpq会丢弃这些行,只报告错误。但在单行模式或分块模式下,部分行可能已经返回给应用程序。因此,应用程序可能会先看到一些PGRES_SINGLE_TUPLEPGRES_TUPLES_CHUNKPGresult对象,然后再看到一个PGRES_FATAL_ERROR对象。为了获得正确的事务语义,如果查询最终失败,应用程序必须能丢弃或撤销之前对这些已处理行所做的操作。

提交更正

如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。