53.2. 查询执行函数
与数据库服务器的连接成功建立后,此处描述的函数用于执行 SQL 查询和命令。
PQexec向 Postgres 提交一个查询并等待结果。PGresult *PQexec(PGconn *conn, const char *query);返回一个 PGresult 指针,也可能返回 NULL 指针。除内存耗尽或无法将查询发送到后端等严重错误外,一般会返回非 NULL 指针。如果返回了 NULL,应将其视同 PGRES_FATAL_ERROR 结果。使用 PQerrorMessage 获取该错误的更多信息。
PGresult 结构封装了后端返回的查询结果。libpq
应用程序员应注意维护
PGresult 的抽象。请使用下面的访问函数获取
PGresult 的内容。避免直接引用
PGresult 结构的字段,因为它们将来可能改变。(从
Postgres 6.4 版开始,libpq-fe.h
中甚至不再提供 struct
PGresult 的定义。如果你有直接访问
PGresult 字段的旧代码,可以通过同时包含
libpq-int.h
继续使用它,但我们建议你尽快修改这些代码。)
PQresultStatus返回查询的结果状态。PQresultStatus 可以返回下列值之一:PGRES_EMPTY_QUERY, PGRES_COMMAND_OK, /* the query was a command returning no data */ PGRES_TUPLES_OK, /* the query successfully returned tuples */ PGRES_COPY_OUT, /* Copy Out (from server) data transfer started */ PGRES_COPY_IN, /* Copy In (to server) data transfer started */ PGRES_BAD_RESPONSE, /* an unexpected response was received */ PGRES_NONFATAL_ERROR, PGRES_FATAL_ERROR
如果结果状态为 PGRES_TUPLES_OK,就可以使用下面描述的例程检索查询返回的元组。注意,碰巧检索到零个元组的 SELECT 仍然显示 PGRES_TUPLES_OK。PGRES_COMMAND_OK 用于永远不会返回元组的命令。
PQresultErrorMessage返回与查询相关联的错误消息;如果没有错误则返回空字符串。const char *PQresultErrorMessage(PGresult *res);
在 PQexec 或 PQgetResult 调用之后紧接着,(连接上的)PQerrorMessage 会返回与(结果上的)PQresultErrorMessage 相同的字符串。但 PGresult 会保留其错误消息直到被销毁,而连接的错误消息会随后续操作而变化。想知道与某个特定 PGresult 相关联的状态时使用 PQresultErrorMessage;想知道连接上最新操作的状态时使用 PQerrorMessage。
PQntuples返回查询结果中的元组(实例)数。int PQntuples(PGresult *res);
PQnfields返回查询结果中每个元组的字段(属性)数。int PQnfields(PGresult *res);
PQbinaryTuples如果 PGresult 包含二进制元组数据则返回 1,包含 ASCII 数据则返回 0。int PQbinaryTuples(PGresult *res);
目前,只有从 BINARY 游标提取数据的查询才能返回二进制元组数据。
PQfname返回与给定字段编号相关联的字段(属性)名。字段编号从 0 开始。char *PQfname(PGresult *res, int field_index);PQfnumber返回与给定字段名相关联的字段(属性)编号。int PQfnumber(PGresult *res, char* field_name);如果给定的名称不匹配任何字段,返回 -1。
PQftype返回与给定字段编号相关联的字段类型。返回的整数是该类型的内部编码。字段编号从 0 开始。Oid PQftype(PGresult *res, int field_num);PQfsize返回与给定字段编号相关联的字段的大小,以字节计。字段编号从 0 开始。int PQfsize(PGresult *res, int field_index);PQfsize 返回数据库元组中为该字段分配的空间,换句话说,即服务器对该数据类型的二进制表示的大小。如果字段是变长的则返回 -1。
PQfmod返回与给定字段编号相关联的字段的类型专属修饰数据。字段编号从 0 开始。int PQfmod(PGresult *res, int field_index);PQgetvalue返回 PGresult 中某个元组的单个字段(属性)值。元组和字段编号都从 0 开始。char* PQgetvalue(PGresult *res, int tup_num, int field_num);对大多数查询而言,PQgetvalue 返回的是属性值的以空字符结尾的 ASCII 字符串表示。但如果 PQbinaryTuples() 为 TRUE,PQgetvalue 返回的就是该类型以后端服务器内部格式表示的二进制表示(若字段为变长则不含大小字)。此时由程序员负责把数据转换成正确的 C 类型。PQgetvalue 返回的指针指向属于 PGresult 结构的存储空间。不应修改它;如果需要在 PGresult 结构的生命周期结束后继续使用该值,就必须显式地将它复制到其他存储空间。
PQgetlength返回字段(属性)的长度,以字节计。元组和字段编号从 0 开始。int PQgetlength(PGresult *res, int tup_num, int field_num);这是该特定数据值的实际数据长度,即 PQgetvalue 所指对象的大小。注意,对于以 ASCII 表示的值,此大小与 PQfsize 报告的二进制大小几乎没有关系。
PQgetisnull测试一个字段是否为 NULL 条目。元组和字段编号从 0 开始。int PQgetisnull(PGresult *res, int tup_num, int field_num);如果字段包含 NULL,此函数返回 1;包含非 NULL 值则返回 0。(注意,对于 NULL 字段,PQgetvalue 返回的是空字符串而不是空指针。)
PQcmdStatus返回生成该 PGresult 的 SQL 命令的命令状态字符串。char *PQcmdStatus(PGresult *res);
PQcmdTuples返回受 SQL 命令影响的行数。const char *PQcmdTuples(PGresult *res);
如果生成该 PGresult 的 SQL 命令是 INSERT、UPDATE 或 DELETE,此函数返回一个包含受影响行数的字符串。如果是其他命令,返回空字符串。
PQoidStatus如果 SQL 命令是一个 INSERT,返回一个含有所插入元组对象 id 的字符串。否则返回空字符串。char* PQoidStatus(PGresult *res);
PQprint打印出所有的元组以及(可选的)属性名到指定的输出流。void PQprint(FILE* fout, /* output stream */ PGresult* res, PQprintOpt* po); struct _PQprintOpt { pqbool header; /* print output field headings and row count */ pqbool align; /* fill align the fields */ pqbool standard; /* old brain dead format */ pqbool html3; /* output html tables */ pqbool expanded; /* expand tables */ pqbool pager; /* use pager for output if needed */ char *fieldSep; /* field separator */ char *tableOpt; /* insert to HTML <table ...> */ char *caption; /* HTML <caption> */ char **fieldName; /* null terminated array of replacement field names */ };此函数旨在取代现已过时的 PQprintTuples()。
psql程序使用 PQprint() 显示查询结果。PQprintTuples打印出所有的元组以及(可选的)属性名到指定的输出流。void PQprintTuples(PGresult* res, FILE* fout, /* output stream */ int printAttName,/* print attribute names or not*/ int terseOutput, /* delimiter bars or not?*/ int width); /* width of column, variable width if 0*/PQdisplayTuples打印出所有的元组以及(可选的)属性名到指定的输出流。void PQdisplayTuples(PGresult* res, FILE* fout, /* output stream */ int fillAlign, /* space fill to align columns */ const char *fieldSep, /* field separator */ int printHeader, /* display headers? */ int quiet); /* suppress print of row count at end */PQdisplayTuples() 本意是取代 PQprintTuples(),而它又被 PQprint() 取代。
PQclear释放与 PGresult 关联的存储。每个查询结果在不再需要时都应通过 PQclear 释放。void PQclear(PQresult *res);
PGresult 对象需要保留多久就可以保留多久;发出新查询时它不会消失,即使关闭连接也不会。要清除它,必须调用 PQclear。不这样做将导致前端应用内存泄漏。
PQmakeEmptyPGresult以给定的状态构造一个空的 PGresult 对象。PGresult* PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status);
这是 libpq 分配并初始化空 PGresult 对象的内部例程。导出它是因为某些应用发现自己生成结果对象(特别是带有错误状态的对象)很有用。如果 conn 非 NULL 且 status 指示一个错误,连接的当前 errorMessage 会被复制到 PGresult。注意,最终也应对该对象调用 PQclear,就像对待 libpq 本身返回的 PGresult 一样。