PostgreSQL 中文参考文档
🌐 英文原版 官方 ↗

32.6. 分块分批获取查询结果 #

通常, libpq 会收集一条 SQL 命令的完整结果, 并把它作为单个 PGresult 返回给应用程序。 对于返回大量行的命令来说, 这可能行不通。 对于这样的情况, 应用程序可以以 单行模式或 分块模式使用 PQsendQuery 和 PQgetResult。 在这些模式中, 结果行会在它们从服务器被收到时返回给应用程序: 单行模式一次一行, 分块模式则成组返回。

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

在使用管道模式时, 需要为管道中的每条查询激活单行或分块模式, 然后才能用 PQgetResult 检索该查询的结果。 更多信息请参见 Section 32.5。

PQsetSingleRowMode #

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

int PQsetSingleRowMode(PGconn *conn);

这个函数只能在 PQsendQuery 或其兄弟函数之一之后立即被调用, 并且在对连接进行任何其他操作 (例如 PQconsumeInput 或 PQgetResult) 之前。 如果在正确的时刻被调用, 该函数会为当前查询激活单行模式并返回 1。 否则该模式保持不变, 并且该函数返回 0。 无论如何, 在当前查询完成之后该模式都会恢复为正常。

PQsetChunkedRowsMode #

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

int PQsetChunkedRowsMode(PGconn *conn, int chunkSize);

这个函数类似于 PQsetSingleRowMode, 只是它指定每个 PGresult 检索至多 chunkSize 行, 而不一定只有一行。 这个函数只能在 PQsendQuery 或其兄弟函数之一之后立即被调用, 并且在对连接进行任何其他操作 (例如 PQconsumeInput 或 PQgetResult) 之前。 如果在正确的时刻被调用, 该函数会为当前查询激活分块模式并返回 1。 否则该模式保持不变, 并且该函数返回 0。 无论如何, 在当前查询完成之后该模式都会恢复为正常。

Caution

在处理一条查询时, 服务器可能返回了一些行, 然后遇到一个错误, 导致该查询被中止。 通常, libpq 会丢弃任何这样的行, 并且只报告该错误。 但在单行或分块模式中, 某些行可能已经被返回给应用程序。 因此, 应用程序将看到一些 PGRES_SINGLE_TUPLE 或 PGRES_TUPLES_CHUNK 的 PGresult 对象后面跟着一个 PGRES_FATAL_ERROR 对象。 为了得到正确的事务行为, 应用程序必须被设计为: 如果查询最终失败, 则丢弃或撤销对之前处理的行所做的一切。