通常,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
对象。为了获得正确的事务行为,如果查询最终失败,则必须将应用程序设计为丢弃或撤消对先前处理的行所做的任何操作。
如果您在文档中看到任何不正确、与您使用特定功能的经验不符或需要进一步澄清的内容,请使用此表单报告文档问题。