通常情况下,libpq 会收集 SQL 命令的全部结果,并将其作为一个 PGresult
返回给应用程序。对于返回大量行的命令,这可能无法处理。在这些情况下,应用程序可以使用 PQsendQuery
和 PQgetResult
以单行模式或分块模式。在这些模式下,结果行(或多行)将在从服务器接收到时返回给应用程序,单行模式下一次返回一行,分块模式下一次返回一组行。
要进入这些模式之一,请在成功调用 PQsendQuery
(或其同级函数)后立即调用 PQsetSingleRowMode
或 PQsetChunkedRowsMode
。此模式选择仅对当前执行的查询有效。然后,重复调用 PQgetResult
,直到它返回 null,具体请参见 第 32.4 节。如果查询返回任何行,它们将作为零个或多个 PGresult
对象返回,这些对象看起来与普通查询结果一样,但状态码分别为 PGRES_SINGLE_TUPLE
(单行模式)或 PGRES_TUPLES_CHUNK
(分块模式),而不是 PGRES_TUPLES_OK
。每个 PGRES_SINGLE_TUPLE
对象包含正好一行,而 PGRES_TUPLES_CHUNK
对象包含至少一行,但不超过每块指定的行数。在最后一行之后,或者在查询返回零行的情况下立即返回一个零行对象,其状态码为 PGRES_TUPLES_OK
;这是没有更多行会到达的信号。(但请注意,仍然有必要继续调用 PQgetResult
直到它返回 null。)所有这些 PGresult
对象都将包含与该查询的普通 PGresult
对象相同的行描述数据(列名、类型等)。每个对象都应使用 PQclear
进行清理,一如既往。
在使用流水线模式时,单行模式或分块模式需要为流水线中的每个查询激活,然后才能使用 PQgetResult
检索该查询的结果。有关更多信息,请参阅 第 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。无论如何,在当前查询完成后,模式将恢复正常。
在处理查询时,服务器可能会返回一些行,然后遇到错误,导致查询被中止。通常情况下,libpq 会丢弃任何此类行,并且只报告错误。但在单行模式或分块模式下,某些行可能已经被返回给应用程序。因此,应用程序将看到一些 PGRES_SINGLE_TUPLE
或 PGRES_TUPLES_CHUNK
PGresult
对象,后面跟着一个 PGRES_FATAL_ERROR
对象。为了正确处理事务,如果查询最终失败,应用程序必须被设计成丢弃或撤销已对先前处理过的行所做的任何操作。
如果您在文档中看到任何不正确的内容,与您在使用特定功能时的体验不符,或者需要进一步的说明,请使用 此表单 来报告文档问题。