0

libpq-feでライブラリを使用しCてpostgresデータベースに接続しています。タイムスタンプを返す
コードを使用してストアドプロシージャを呼び出しています。 このタイムスタンプをchar配列に保存したいと思います。ただし、そのためには、配列を宣言できるように、最初にタイムスタンプのサイズを知る必要があります。私が使用しているサイズを取得するには。あなたはそれについてもっとここで見つけることができます。 libpqfe
int PQfsize(PGresult *res, int field_index);

値を返します8。ただし、実際にはタイムスタンプのサイズ(ゾーンなし)は19です。

PQfsizeが間違った値を返すのはなぜですか?

タイムスタンプのサイズは一定であり、配列を直接宣言してから、を使用して値を取得できますが、PQgetvalueサイズが固定されていないフィールドの配列を宣言する方法を知っています。

フィールドを取得しPGresultて任意の変数に格納するにはどうすればよいですか?

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を返す必要があります)を使用し、0としてデータをテキストとして取得するように指定しますPQexecParams。デフォルトでは、データはテキスト形式で返されます。resultFormatPQexec

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、サーバーの内部バイナリ表現のバイト数を返しますtimestamp

また、timestampaのストレージサイズは8バイトです。timestamp基本的に、あなたはあなたが探している人間が読める文字列ではなく、サーバーの内部バイトを取得しています。

バイナリ値ではなく、結果のテキスト値を取得するには、ゼロに設定して使用することPQExecParamsをお勧めします。resultFormatこれを行うと、期待しているの文字列表現を取得する必要がありますが、の内容をネイティブタイプtimestampに変換するには、文字列の解析を少し行う必要があります。PGresult

于 2012-12-27T17:47:24.643 に答える