0

I am using the libpq-fe library in C to contact to a postgres database.
I am calling a stored procedure from my code using libpqfe which returns a timestamp.
I want to store this timestamp to a char array. But to do so I first have to know the size of timestamp so that I can declare the array. To get the size I am using int PQfsize(PGresult *res, int field_index);. You can found more about it here.

It returns the value 8. But actually the size of the timestamp(without zone) is 19.

Why PQfsize is returning wrong value?

I know that size of the timestamp is constant and I can directly declare an array and then retrieve the value using PQgetvalue, but how to declare arrays for the fields which don't have fixed size.

How to retrieve a field from PGresult to store it into any variable?

4

2 回答 2

3

PQfsize 没有返回错误的值。

如果您运行下面的查询,您还将得到答案 8,因为在您的 Postgres 版本内部,时间戳存储为 8 字节(64 位)整数。

select typlen from pg_type where oid = 'timestamp'::regtype::oid;

根据您链接的文档, PQfsize 返回为数据库元组中的该字段分配的空间,换句话说,服务器的数据类型二进制表示的大小。

PQgetlength 返回字段(属性)的长度(以字节为单位)。元组和字段索引从 0 开始。

这是特定数据值的实际数据长度,即 PQgetvalue 指向的对象的大小。请注意,对于 ASCII 表示的值,此大小与PQfsize.

为了声明没有固定大小的数组,在创建它之前使用数组的大小PQgetlength(应该返回 19)并通过指定将数据作为文本获取PQexecParamsresultFormat0。如果你只是使用PQexecthen数据默认以文本形式返回。

此处提供了使用 libpq 的示例。

要修改此示例,以便仅打印值,它会根据数据的长度创建一个字符数组并将数据复制到数组中,您可以将 for 循环替换为类似的内容

      for (i = 0; i < PQntuples(res); i++)                
      {
           int length = PQgetlength(res, i, 0);
           char result[length];
           printf("%s\n", PQgetvalue(res, i, 0));           
           strncpy (result,PQgetvalue(res, i, 0),length);
      }

您还需要添加#include <string.h>到示例中。

于 2012-12-27T18:37:46.090 回答
1

来自精美手册

PQfsize返回在数据库行中为该列分配的空间,即服务器内部数据类型表示的大小。

因此PQfsize返回服务器内部二进制表示中的字节数 a timestamp

atimestamp的存储大小为 8 个字节。基本上,你得到的是服务器的内部timestamp字节,而不是你正在寻找的人类可读的字符串。

您可能希望使用PQExecParamswith resultFormatset to zero 来获取结果中的文本值,而不是二进制值。如果你这样做,你应该得到timestamp你期望的 a 的字符串表示,但是你必须做一些字符串解析来将 a 的内容转换为本PGresult机类型。

于 2012-12-27T17:47:24.643 回答