コマンド実行関数

PostgreSQL 8.4.1文書
前のページ | 巻戻し | 第 30章libpq - C ライブラリ | 早送り | 次のページ

# 30.3. コマンド実行関数

いったんデータベースサーバへの接続の確立が成功すれば、この節で説明する関数を使って SQL の問い合わせやコマンドを実行します。

## 30.3.1. メイン関数

`PQexec`

  コマンドをサーバに送信し、結果を待機します。

               PGresult *PQexec(PGconn *conn, const char *command);

  戻り値は `PGresult` へのポインタ、場合によってはNULLポインタです。 メモリ不足の状態、あるいはサーバへのコマンド送信が不可能といった深刻なエラーの場合を除けば、通常非NULLのポインタが返ります。 戻り値がNULLポインタの場合には、`PGRES_FATAL_ERROR` が起こった場合と同様に扱われなければいけません。 こうしたエラーの詳しい情報は、`PQerrorMessage` で得ることができます。

コマンド文字列には(セミコロンで区切った)複数のSQLコマンドを含めることができます。 単一の`PQexec`呼び出しで送信された複数の問い合わせは、単一トランザクションで処理されます。 ただし、問い合わせ文字列内に明示的な`BEGIN`/`COMMIT`がある場合は、複数のトランザクションに分離されます。 しかし、返される`PGresult`構造体はその文字列内で最後に実行されたコマンドの結果のみが含まれることに注意してください。 そのコマンドの1つが失敗したとすると、文字列の処理はそこで中断し、エラー条件が含まれる`PGresult`が返されます。

`PQexecParams`

  サーバにコマンドを送信し、結果を待ちます。 ただし、SQLコマンドテキストとは別にパラメータを渡すことができます。

      PGresult *PQexecParams(PGconn *conn,
                             const char *command,
                             int nParams,
                             const Oid *paramTypes,
                             const char * const *paramValues,
                             const int *paramLengths,
                             const int *paramFormats,
                             int resultFormat);

  `PQexecParams`と`PQexec`は似ていますが、前者は次の機能が追加されています。 パラメータ値をコマンド文字列とは別に適切に指定することができ、また、問い合わせの結果をテキスト書式としてでもバイナリ書式としてでも要求できます。 `PQexecParams`はプロトコル3.0以降でのみサポートされ、プロトコル2.0で使用した場合は失敗します。

  この関数の引数を以下に示します。

  `conn`

    接続オブジェクトです。これを通してコマンドを送信します。

  `command`

    実行させるSQLコマンド文字列です。 パラメータが使用される場合は、コマンド文字列内で`$1`、`$2`などのように参照されます。

  `nParams`

    提供するパラメータ数です。 これは配列`paramTypes[]`、`paramValues[]`、`paramLengths[]`、`paramFormats[]`の要素数です。 （この配列ポインタは、`nParams`が0の場合、`NULL`とすることができます。）

  `paramTypes[]`

    パラメータシンボルに代入されるデータ型をOIDで指定したものです。 `paramTypes`が`NULL`または、ある配列要素が0の場合、サーバは、型指定のないリテラル文字列に対して行う推定方法と同じ方法を使用して、パラメータシンボルのデータ型を推定します。

  `paramValues[]`

    パラメータの実際の値を指定します。 配列内のNULLポインタは対応するパラメータがNULLであることを意味します。 さもなくば、このポインタはゼロ終端のテキスト文字列（テキスト書式）、または、サーバで想定している書式によるバイナリデータ（バイナリ書式）を指し示します。

  `paramLengths[]`

    バイナリ書式のパラメータの実データ長を指定します。 NULLパラメータおよびテキスト書式のパラメータでは無視されます。 バイナリパラメータが存在しない場合、この配列ポインタはNULLとしてもかまいません。

  `paramFormats[]`

    パラメータがテキスト（パラメータに対応する配列要素に0を設定）か、バイナリ（パラメータに対応する配列要素に1を設定）かを指定します。 この配列ポインタがNULLの場合、すべてのパラメータはテキスト文字列であると仮定されます。

    バイナリ書式で渡された値は、バックエンドが想定する内部表現の知識を必要とします。 例えば、整数はネットワークバイト順に渡されなければなりません。`数値`による値は、 `src/backend/utils/adt/numeric.c::numeric_send()`および `src/backend/utils/adt/numeric.c::numeric_recv()` で実装されたようにサーバストレージ書式の知識を必要とします。

  `resultFormat`

    結果をテキスト書式で取り出したい場合は0を、バイナリ書式で取り出したい場合は1を指定します。 （現時点では、プロトコル内部では実現可能ですが、結果の列ごとにを異なる書式を指定して取り出す機構は存在しません。）

`PQexec`に対する`PQexecParams`の主要な利点は、コマンド文字列とパラメータ値を分離可能である点です。 これにより、退屈でエラーを招きやすい引用符付けやエスケープ処理を行なう必要がなくなります。

`PQexec`と異なり、`PQexecParams`は、文字列内に最大でも1つのSQLコマンドを入れることができます。 (セミコロンを入れることはできますが、空でないコマンドを1つ以上入れることはできません。) これは、プロトコル自体の制限ですが、SQL混入攻撃に対する追加の防御となる点より多少役に立ちます。

> ティップ: OID経由のパラメータ型の指定は、特にプログラムの中で特定のOID値が組込みになることを好まない場合には退屈です。 しかしながら、パラメータの型をサーバ自身で決定できない場合や、望む型と異なる型を選択する場合に、これを避けることができます。 SQLコマンドテキストでどのデータ型を送信するかを示すためにパラメータシンボルに明示的にキャストをつけてください。 以下が例です。

>     SELECT * FROM mytable WHERE x = $1::bigint;

> デフォルトではパラメータ`$1`の型は`x`と同じデータ型に割り当てられますが、これにより強制的に`bigint`として扱われます。 この方法または型のOIDを数字で指定する方法で、パラメータの型を強制的に決定することがバイナリフォーマットにおいてパラメータ値を送る時に強く推奨されます。 これは、バイナリフォーマットがテキストフォーマットより情報が少なく、そのために、サーバが型の不一致という問題を検出する機会が少なくなるためです。

`PQprepare`

  指定パラメータを持つプリペアド文の作成要求を送信し、その完了を待ちます。

      PGresult *PQprepare(PGconn *conn,
                          const char *stmtName,
                          const char *query,
                          int nParams,
                          const Oid *paramTypes);

  `PQprepare`は、後で`PQexecPrepared`を使用して実行するプリペアド文を作成します。 この機能を使用して、繰り返し使用されるコマンドの解析と計画作成を実行時毎回行うのではなく、一回のみ行うようにすることができます。 `PQprepare`はプロトコル3.0以降でのみサポートされ、プロトコル2.0を使用している場合は失敗します。

  この関数は`query`文字列から`stmtName`という名前のプリペアド文を作成します。 `query`は単一のSQLコマンドでなければなりません。 `stmtName`を`""`にして、無名の文を作成することができます。 もし、無名の文が既に存在していた場合は自動的に置き換えられます。 その他の場合、文の名前が現在のセッションで既に存在するとエラーになります。 何らかのパラメータが使用される場合、問い合わせ内では`$1`、`$2`などで参照します。 `nParams`はパラメータ数です。 その型については事前に`paramTypes[]`配列で指定されています。 (`nParams`がゼロの場合、この配列ポインタは`NULL`にすることができます。) `paramTypes[]`は、OIDによりパラメータシンボルに割り当てるデータ型を指定します。 `paramTypes`が`NULL`の場合、もしくは、配列内の特定要素がゼロの場合、サーバはそのパラメータシンボルに対して、型指定の無いリテラル文字列に対する処理と同等の方法でデータ型を割り当てます。 また、問い合わせでは`nParams`より多くのパラメータシンボルを使用することができます。 これらのシンボルに対するデータ型も同様に推測されます。 （どのようなデータ型が推測されるかを検出する手法については`PQdescribePrepared`を参照してください。）

  `PQexec`同様、結果は通常`PGresult`オブジェクトで、その内容でサーバ側の成功や失敗を示します。 NULLという結果はメモリ不足や全くコマンドを送信することができなかったことを示します。 こうしたエラーの詳細情報を入手するには`PQerrorMessage`を使用してください。

`PQexecPrepared`で使用するためのプリペアド文は、PREPARE SQL文を実行することでも作成可能です。 (しかし、`PQprepare`はパラメータの型を事前に定義する必要がありませんので、より柔軟性があります。) また、プリペアド文を削除するlibpq関数はありませんが、この目的のためにDEALLOCATESQL文を使用することができます。

`PQexecPrepared`

  指定パラメータによるプリペアド文の実行要求を送信し、結果を待ちます。

      PGresult *PQexecPrepared(PGconn *conn,
                               const char *stmtName,
                               int nParams,
                               const char * const *paramValues,
                               const int *paramLengths,
                               const int *paramFormats,
                               int resultFormat);

  `PQexecPrepared`と`PQexecParams`は似ていますが、前者では実行されるコマンドは、問い合わせ文字列を与えるのではなく、事前にプリペアド文を指名することで指定されます。 この機能により、繰り返し使用する予定のコマンドを実行する度にではなく、一度だけ解析、計画作成を行なうことができます。 この文は現在のセッションで事前に準備されていなければなりません。 `PQexecPrepared`は、プロトコル3.0以降の接続でのみサポートされます。 プロトコル2.0で使用した場合は失敗します。

  パラメータは、問い合わせ文字列ではなく指定されたプリペアド文の名前を与える点を除き、`PQexecParams`と同じです。 また、`paramTypes[]`パラメータは存在しません。 (プリペアド文のパラメータ型はその作成時点で決定されているため、これは不要です。)

`PQdescribePrepared`

  指定したプリペアド文に関する情報入手要求を送り、入手完了まで待機します。

      PGresult *PQdescribePrepared(PGconn *conn, const char *stmtName);

  `PQdescribePrepared`により、アプリケーションは事前にプリペアド文に関する情報を入手できます。 `PQdescribePrepared`はプロトコル3.0以降の接続でのみサポートされます。 プロトコル2.0で使用すると失敗します。

  `stmtName`を`""`またはNULLとすることで、無名の文を参照することができます。 これ以外では、存在するプリペアド文の名前でなければなりません。 成功すると、`PGRES_COMMAND_OK`というステータスの`PGresult`が返されます。 関数`PQnparams`および`PQparamtype`をこの`PGresult`に適用して、プリペアド文のパラメータに関する情報を得ることができます。 また、関数`PQnfields`、`PQfname`、`PQftype`などを使用して、文の結果列（もしあれば）に関する情報を提供できます。

`PQdescribePortal`

  指定したポータルに関する情報入手要求を送信し、完了まで待機します。

      PGresult *PQdescribePortal(PGconn *conn, const char *portalName);

  `PQdescribePortal`により、アプリケーションは事前に作成されたポータルの情報を入手することができます。 （libpqはポータルへの直接アクセスする方法を提供していませんが、この関数を使用して`DECLARE CURSOR` SQLコマンドで作成したカーソルの属性を確認することができます。） `PQdescribePortal`はプロトコル3.0以降の接続でのみサポートされます。 プロトコル2.0で使用すると失敗します。

  `portalName`に`""`またはNULLを指定して、無名のポータルを参照することができます。 これ以外では、既存のポータルの名前でなければなりません。 成功すると、`PGRES_COMMAND_OK`というステータスの`PGresult`が返されます。 関数`PQnfields`、`PQfname`、`PQftype`などをこの`PGresult`に適用して、ポータルの結果列（もしあれば）に関する情報を得ることができます。

`PGresult`構造体はサーバから返された結果をカプセル化します。 libpqアプリケーションのプログラマは注意して`PGresult`という抽象化を維持してください。 以下のアクセス用関数を使用して、`PGresult`の内容を取り出してください。 将来の変更に影響されますので、`PGresult`構造体のフィールドを直接参照することは避けてください。

`PQresultStatus`

  コマンドの結果状態を返します。

               ExecStatusType PQresultStatus(const PGresult *res);

  `PQresultStatus`は以下のいずれかの値を返します。

  `PGRES_EMPTY_QUERY`

    サーバに送信された文字列が空でした。

  `PGRES_COMMAND_OK`

    データを返さないコマンドが正常終了しました。

  `PGRES_TUPLES_OK`

    データを返すコマンド(`SELECT`や`SHOW`など)が正常終了しました。

  `PGRES_COPY_OUT`

    (サーバからの)コピーアウトデータ転送が始まりました。

  `PGRES_COPY_IN`

    (サーバへの)コピーインデータ転送が始まりました。

  `PGRES_BAD_RESPONSE`

    サーバが不明な応答を返しました。

  `PGRES_NONFATAL_ERROR`

    致命的ではない(注意喚起もしくは警告)エラーが発生しました。

  `PGRES_FATAL_ERROR`

    致命的なエラーが発生しました。

  結果状態が`PGRES_TUPLES_OK`であれば、以下で説明する関数を使って問い合わせが返した行を取り出すことができます。 ただし、たまたま`SELECT`コマンドが返す行が0個だったような場合でも`PGRES_TUPLES_OK`となることに注意してください。 `PGRES_COMMAND_OK`は、行を全く返さない(`INSERT`、`UPDATE`などの)コマンド用です。 `PGRES_EMPTY_QUERY`という応答はクライアントソフトウェアの不具合を示しているかもしれません。

  `PGRES_NONFATAL_ERROR`状態の場合、結果は`PQexec`や他の問い合わせ実行関数によって直接返されません。 その代わりに、この種の結果は注意喚起処理器(項30.11参照)に渡されます。

`PQresStatus`

  `PQresultStatus`が返す列挙型から状態コードを説明する文字列定数に変換します。 呼び出し元はこの結果を解放してはいけません。

               char *PQresStatus(ExecStatusType status);

`PQresultErrorMessage`

  コマンドに関するエラーメッセージを返します。 エラーが何もなければ、空の文字列を返します。

               char *PQresultErrorMessage(const PGresult *res);

  エラーがあった場合、返される文字列の最後には改行が含まれます。 呼び出し元はこの結果を直接解放してはいけません。 関連する`PGresult`ハンドルが`PQclear`に渡された時にこれは解放されます。

  （接続に対する）`PQerrorMessage`も、`PQexec`または`PQgetResult`呼び出しの直後なら（結果に対する）`PQresultErrorMessage`と同じ文字列を返します。 しかし、接続に対するエラーメッセージは後続する操作を実行すると変化してしまうのに対し、`PGresult`はオブジェクトが破棄されるまでそのエラーメッセージを維持し続けます。 この`PQresultErrorMessage`は個々の`PGresult`に結び付けられた状態を見る時に、そして`PQerrorMessage`は接続における最後の操作の状態を見る時に使用してください。

`PQresultErrorField`

  エラー報告の個々のフィールドを返します。

               char *PQresultErrorField(const PGresult *res, int fieldcode);

  `fieldcode`はエラーフィールド識別子です。 以下に示すシンボルを参照してください。 `PGresult`がエラーではない、もしくは、警告付きの結果である場合や指定したフィールドを含まない場合、`NULL`が返されます。 通常フィールド値には改行が含まれません。 フィールド値は関連する`PGresult`ハンドルが`PQclear`に渡された時に開放されます。

  以下のフィールドコードが使用できます。

  `PG_DIAG_SEVERITY`

    深刻度。 このフィールドの内容は(エラーメッセージの場合)`ERROR`、`FATAL`、もしくは、`PANIC`、(注意喚起メッセージの場合)`WARNING`、`NOTICE`、`DEBUG`、`INFO`、もしくは、`LOG`です。 これらは、多言語化により翻訳されている可能性があります。 常に存在します。

  `PG_DIAG_SQLSTATE`

    エラーのSQLSTATEコードです。 SQLSTATEコードは発生したエラーの種類を識別します。 フロントエンドアプリケーションにより、特定のデータベースエラーに対して所定の操作（エラー処理など）を行うために使用できます。 起こり得るSQLSTATEコードの一覧については付録Aを参照してください。 このフィールドは多言語化されておらず、また、常に存在します。

  `PG_DIAG_MESSAGE_PRIMARY`

    主に可読性を高めたエラーメッセージです。 (通常は1行です。) 常に存在します。

  `PG_DIAG_MESSAGE_DETAIL`

    詳細です。 問題に関するより詳細を表す補助的なエラーメッセージです。 複数行に跨る可能性があります。

  `PG_DIAG_MESSAGE_HINT`

    ヒントです。 問題の対応方法についての補助的な提言です。 これは、詳細(detail)とは異なり、問題の事象ではなく、(適切でない可能性がありますが)アドバイスを提供することを目的としています。 複数行に跨る可能性があります。

  `PG_DIAG_STATEMENT_POSITION`

    元の問い合わせ文字列のインデックスとなるエラーが発生したカーソル一を示す10進整数を持つ文字列です。 先頭文字がインデックス1となり、また、バイトではなく、文字数で数えた位置です。

  `PG_DIAG_INTERNAL_POSITION`

    この定義は`PG_DIAG_STATEMENT_POSITION`フィールドと同じです。 しかし、これは、クライアントが発行したコマンドではなく、カーソル位置が内部生成コマンドを参照する場合に使用されます。 このフィールドが存在する時は常に`PG_DIAG_INTERNAL_QUERY`フィールドが存在します。

  `PG_DIAG_INTERNAL_QUERY`

    失敗した内部生成コマンドのテキストです。 これは、例えば、PL/pgSQL関数で発行されたSQL問い合わせになります。

  `PG_DIAG_CONTEXT`

    エラーが発生した文脈を示すものです。 今の所、これは活動中の手続き言語関数や内部生成問い合わせの呼び出しスタックの追跡情報が含まれます。 この追跡は行単位で1項目であり、その順番は呼び出し順の反対になります。

  `PG_DIAG_SOURCE_FILE`

    エラーが報告された場所のソースコードのファイル名です。

  `PG_DIAG_SOURCE_LINE`

    エラーが報告された場所のソースコードにおける行番号です。

  `PG_DIAG_SOURCE_FUNCTION`

    エラーを報告した、ソースコードにおける関数名です。

  必要に応じた表示される情報の整形はクライアントの責任です。 具体的には、必要に応じて長い行を分割します。 エラーメッセージフィールド内の改行文字は、改行としてではなく段落として分かれたものとして取扱うべきです。

  libpqで内部的に生成されたエラーは、深刻度と主要メッセージを持ちますが、通常は他のフィールドを持ちません。 3.0より前のプロトコルのサーバで返されるエラーは、深刻度と主要メッセージ、場合によって詳細メッセージを持ちますが、他のフィールドを持ちません。

  エラーフィールドは`PGresult`からのみ利用でき、`PGconn`からは利用できません。 `PQerrorField`という関数はありません。

`PQclear`

  `PGresult` に割り当てられた記憶領域を解放します。 個々の問い合わせ結果は、必要なくなった時に `PQclear`で解放するべきです。

               void PQclear(PGresult *res);

  `PGresult`オブジェクトは、必要な間保持することができます。 新しい問い合わせを発行する場合でも、接続を閉じてしまうまでは`PGresult`は消えません。 `PGresult`を解放するには、`PQclear`を呼び出さなくてはいけません。 その操作に失敗してしまうと、アプリケーションのメモリリークを引き起こしてしまいます。

## 30.3.2. 問い合わせ結果の情報の取り出し

これらの関数を使用して、正常終了した問い合わせ結果を示す(つまり、その状態が`PGRES_TUPLES_OK`となっている)`PGresult`オブジェクトから情報を抽出することができます。 また、成功したDescribe操作から情報を抽出することもできます。 Describeの結果はすべて、実際に問い合わせを実行した時に提供されるものと同じ列情報を持ちますが、行はありません。 他の状態値を持つオブジェクトでは、これらの関数は、結果が0行0列であるものと同様に動作します。

`PQntuples`

  問い合わせ結果内の行(タプル)数を返します。 これは整数を結果として返しますので、32ビットオペレーティングシステムでは、大規模な結果セットの戻り値はオーバーフローする可能性があります。

              int PQntuples(const PGresult *res);

`PQnfields`

  問い合わせ結果の各行の列(フィールド)の数を返します。

              int PQnfields(const PGresult *res);

`PQfname`

  指定した列番号に対応する列の名前を返します。 列番号は0から始まります。 呼び出し元はこの結果を直接解放してはいけません。 関連する`PGresult`ハンドルが`PQclear`に渡された時にこれは解放されます。

              char *PQfname(const PGresult *res,
                  int column_number);

  列番号が範囲外であった場合、`NULL` が返ります。

`PQfnumber`

  指定した列名に関連する列番号を返します。

              int PQfnumber(const PGresult *res,
                            const char *column_name);

  指定した名前に一致する列がなければ、-1が返ります。

  指定した名前はSQLコマンドの識別子同様に扱われます。 つまり、二重引用符で括られていない限り、小文字化されます。 例えば、以下のSQlで生成された問い合わせ結果を考えます。

      SELECT 1 AS FOO, 2 AS "BAR";

  以下により、結果を取り出すことができます。

      PQfname(res, 0)              foo
      PQfname(res, 1)              BAR
      PQfnumber(res, "FOO")        0
      PQfnumber(res, "foo")        0
      PQfnumber(res, "BAR")        -1
      PQfnumber(res, "\"BAR\"")    1

`PQftable`

  指定した列の抽出元であるテーブルのOIDを返します。 列番号は0から始まります。

              Oid PQftable(const PGresult *res,
                           int column_number);

  列番号が範囲外の場合や指定した列がテーブル列への単純な参照でない場合、3.0より前のプロトコルを使用している場合は、`InvalidOid`が返されます。 `pg_class`システムテーブルに問い合わせ、どのテーブルが参照されているのかを正確に求めることができます。

  libpqヘッダファイルをインクルードすると、`Oid`型と`InvalidOid`定数が定義されます。 これらは両方とも何らかの整数型です。

`PQftablecol`

  指定した問い合わせ結果の列を作成した列の(それが属するテーブル内での)列番号を返します。 問い合わせ結果の列番号は0から始まります。 テーブル列には0以外の番号が付けられています。

             int PQftablecol(const PGresult *res,
                             int column_number);

  列番号が範囲外の場合や指定した列がテーブル列への単純な参照でなかった場合、3.0より前のプロトコルを使用している場合は、ゼロが返されます。

`PQfformat`

  指定した列の書式を示す書式コードが返ります。 列番号は0から始まります。

              int PQfformat(const PGresult *res,
                            int column_number);

  ゼロという書式コードはテキストデータ表現を示し、1という書式コードはバイナリ表現を示します。 (他のコードは将来の定義のために予約されています。)

`PQftype`

  指定した列番号に関連したデータ型を返します。 返された整数は、その型の内部的なOID番号です。 列番号は0から始まります。

              Oid PQftype(const PGresult *res,
                          int column_number);

  `pg_type`システムテーブルに問い合わせて、各種データ型の名前や属性を得ることができます。 組み込みデータ型のOIDは、ソースツリー内の`src/include/catalog/pg_type.h`ファイル内で定義されています。

`PQfmod`

  指定した列番号に関連した列の型修飾子を返します。 列番号は0から始まります。

              int PQfmod(const PGresult *res,
                         int column_number);

  修飾子の値の解釈は型に固有なものです。 通常、これらは精度やサイズの制限を示します。 -1という値は"使用できる情報がない"ことを示します。 ほとんどのデータ型は修飾子を使用しません。この場合は常に-1という値になります。

`PQfsize`

  指定した列番号に関連した列のバイト単位のサイズを返します。 列番号は0から始まります。

              int PQfsize(const PGresult *res,
                          int column_number);

  `PQfsize`はデータベース行内でその列用に割り当てられる領域を返します。 言い替えると、そのデータ型についてのサーバでの内部表現のサイズです。 (従って、実際にはクライアントから見るとあまり役には立ちません。) 負の値は可変長データ型を示します。

`PQbinaryTuples`

  `PGresult`がバイナリデータを持つ場合は1を、テキストデータを持つ場合は0を返します。

              int PQbinaryTuples(const PGresult *res);

  この関数は廃れたものです。 (`COPY`を行う接続での使用を除きます。) 単一の`PGresult`で、ある列はテキストデータを持ち、他の列ではバイナリデータを持つことが可能であるためです。 `PQfformat` の利用が推奨されます。 結果のすべての列がバイナリ(書式1)の場合のみ`PQbinaryTuples`は1を返します。

`PQgetvalue`

  `PGresult`の1行における単一フィールドの値を返します。 行番号と列番号は0から始まります。 呼び出し元はこの結果を直接解放してはいけません。 関連する`PGresult`ハンドルが`PQclear`に渡された時にこれは解放されます。

              char *PQgetvalue(const PGresult *res,
                               int row_number,
                               int column_number);

  テキスト書式のデータでは、`PQgetvalue`で返される値はフィールド値をNULL終端の文字列表現となります。 バイナリ書式のデータでは、この値はデータ型の`typsend`関数と`typreceive`関数で決まるバイナリ表現となります。 (実際にはこの場合でも値の終わりにゼロというバイトが付与されます。 しかし、この値の内部には大抵の場合NULLが埋め込まれていますので、通常このバイトは有用ではありません。)

  フィールド値がNULLの場合、空文字列が返されます。 NULL値と空文字列という値とを区別する方法は`PQgetisnull`を参照してください。

  `PQgetvalue`によって返されるポインタは、`PGresult`構造体の一部の格納領域を指し示します。 このポインタが指し示すデータを変更すべきではありません。 また、`PGresult`構造体を解放した後も使用し続ける場合はデータを別の格納領域に明示的にコピーしなければなりません。

`PQgetisnull`

  フィールドがNULL値かどうか検査します。 行番号と列番号は0から始まります。

              int PQgetisnull(const PGresult *res,
                              int row_number,
                              int column_number);

  この関数は、フィールドがNULLの場合に1を、フィールドが非NULL値を持つ場合は0を返します。 (`PQgetvalue`では、NULLフィールドはNULLポインタではなく空文字列を返すことに注意してください。)

`PQgetlength`

  実際のフィールド値の長さをバイト単位で返します。 行番号と列番号は0から始まります。

              int PQgetlength(const PGresult *res,
                              int row_number,
                              int column_number);

  これは特定のデータ値についての実際のデータ長です。 つまり、`PQgetvalue`によって指し示されるオブジェクトのサイズです。 テキストデータ書式では`strlen()`と同一です。 バイナリ書式ではこれは重要な情報です。 実際のデータ長を取り出すために`PQfsize`を信用してはなりません。

`PQnparams`

  プリペアド文のパラメータ数を返します。

              int PQnparams(const PGresult *res);

  この関数は、`PQdescribePrepared`の結果を確認するときにのみ有用です。 他の種類の問い合わせではゼロを返します。

`PQparamtype`

  指定された文パラメータのデータ型を返します。 パラメータ番号は0から始まります。

              Oid PQparamtype(const PGresult *res, int param_number);

  この関数は、`PQdescribePrepared`の結果を確認するときにのみ有用です。 他の種類の問い合わせではゼロを返します。

`PQprint`

  全ての行と列名(省略可能)を指定した出力ストリームに表示します。

      void PQprint(FILE *fout,      /* 出力ストリーム */
                   const PGresult *res,
                   const PQprintOpt *po);

      typedef struct {
          pqbool  header;      /* フィールドヘッダ情報と行数の表示出力 */
          pqbool  align;       /* 位置揃えのためのフィールドへの埋め込み */
          pqbool  standard;    /* 古い、無くなりそうな書式 */
          pqbool  html3;       /* HTML表出力 */
          pqbool  expanded;    /* 拡張テーブル */
          pqbool  pager;       /* 必要に応じたページャの使用 */
          char    *fieldSep;   /* フィールド区切り文字 */
          char    *tableOpt;   /* HTML表要素の属性 */
          char    *caption;    /* HTML 表の表題 */
          char    **fieldName; /* フィールド名を置き換えるNULL終端の配列 */
      } PQprintOpt;

  この関数は以前問い合わせ結果を表示するためにpsqlで使用されていましたが、今ではもう使用されていません。 これは全てのデータがテキスト書式であるという前提で動作することに注意してください。

## 30.3.3. 他のコマンド用の結果情報の取り出し

これらの関数は`SELECT`結果以外の`PGresult`オブジェクトから情報を取り出すために使用されます。

`PQcmdStatus`

  `PGresult`を生成したSQLコマンドのコマンド状態タグを返します。

              char *PQcmdStatus(PGresult *res);

  これは通常単なるコマンド名ですが、処理行数など追加情報が含まれる場合もあります。 呼び出し元はこの戻り値を直接解放してはいけません。 関連する`PGresult`ハンドルが`PQclear`に渡された時にこれは解放されます。

`PQcmdTuples`

  SQLコマンドにより影響を受けた行数を返します。

              char *PQcmdTuples(PGresult *res);

  `PGresult`を生成したSQLコマンドにより影響を受けた行数を持つ文字列を返します。 この関数は`INSERT`、`UPDATE`、`DELETE`、`MOVE`、`FETCH`、`COPY`文の実行、あるいは、`INSERT`、`UPDATE`、`DELETE`を含む準備済みの問い合わせの`EXECUTE`文の後でのみ使用することができます。 `PGresult`を生成したコマンドが他のコマンドであった場合、`PQcmdTuples`は空文字列を返します。 呼び出し元はこの戻り値を直接解放してはいけません。 関連する`PGresult`ハンドルが`PQclear`に渡された時にこれは解放されます。

`PQoidValue`

  SQLコマンドが、OIDを持つテーブル内に1行のみを挿入する`INSERT`だった場合、あるいは、適切な`INSERT`を持つ準備済みの問い合わせの`EXECUTE`だった場合に、挿入された行のOIDを返します。 さもなくば`InvalidOid`を返します。 また、`INSERT`文の影響を受けたテーブルがOIDを持たなかった場合、この関数は`InvalidOid`を返します。

              Oid PQoidValue(const PGresult *res);

`PQoidStatus`

  SQLコマンドが1行のみを挿入する`INSERT`であった場合、あるいは、適切な`INSERT`を持つプリペアド文の`EXECUTE`であった場合、挿入された行のOIDを文字列で返します。 (`INSERT`が複数行を挿入した場合や対象テーブルがOIDを持たない場合は、`0`という文字列を返します。) コマンドが`INSERT`でなければ、空文字列を返します。

              char *PQoidStatus(const PGresult *res);

  この関数は`PQoidValue`のために廃れたものになりました。 これはスレッドセーフではありません。

## 30.3.4. SQLコマンドに含めるための文字列のエスケープ処理

`PQescapeStringConn`は、SQLコマンド内で使用するために文字列をエスケープします。 これは、SQLコマンド内のリテラル定数としてデータ値を挿入する時に有用です。 特定の文字(引用符やバックスラッシュ)は、SQLパーサによって特殊な解釈がなされないようにエスケープされなければなりません。 `PQescapeStringConn`はこの操作を行ないます。

> ティップ: 信用できない入力元から受けとった文字列を扱う場合に適切なエスケープ処理を行なうことは非常に重要です。 さもなくば、セキュリティ上の危険性が発生します。 "SQL混入"攻撃という弱点となり、好ましくないSQLコマンドがデータベースに流れてしまいます。

`PQexecParams`やその派生ルーチンを使用して分離されたパラメータとしてデータ値を渡す場合は、エスケープ処理は必要がなく、また、不正確になることに注意してください。

         size_t PQescapeStringConn (PGconn *conn,
                                    char *to, const char *from, size_t length,
                                    int *error);

`PQescapeStringConn` は、 `from`文字列を特殊文字をエスケープし問題が起こらないようにし、さらに終端のゼロバイトを追加して`to`バッファに書き込みます。PostgreSQLの文字リテラルとして囲まれるべき単一引用符は結果文字列に含まれません。これは、結果をSQLコマンドに挿入するときに付与しなければなりません。 `from`パラメータは、エスケープ対象の文字列の先頭を指すポインタです。 `length`パラメータはこの文字列のバイト数を示します。 ゼロバイトによる終端は必要なく、また、`lenth`ではこれを数えてはなりません。 (もし`length`バイト処理する前に終端を表す1バイトのゼロが存在すると、`PQescapeStringConn`はそのゼロで終了します。 この動作は`strncpy`と同様です。) `to`は、最低でも`length`の2倍よりも1バイト多い文字を保持可能なバッファへのポインタにしなければなりません。 さもないと、動作は不定になります。 `to` と`from`文字領域が重なる場合の動作は不定です。

`error` パラメータがNULLでなければ、`*error` には成功の0か、エラーの0以外がセットされます。 現時点であり得る唯一のエラー条件は、元文字列に無効なマルチバイト符号が含まれている場合です。 出力文字列はエラーであっても生成されますが、サーバが不整合として却下すると考えられます。エラーの際、適切なメッセージは`error`がNULLかどうかにかかわらず`conn`オブジェクト内に格納されます。

`PQescapeStringConn`は`to`に書き出したバイト数を返します。 ただし、文字数には終端を表す1バイトのゼロは含まれません。

         size_t PQescapeString (char *to, const char *from, size_t length);

`PQescapeString`は`PQescapeStringConn`の推奨されない古いものです。 違いは、`conn`や`error`パラメータを取らないことです。 これは、`PQescapeString`が(文字エンコーディングのような)接続プロパティーによる振舞を調整できないこと、そして間違った結果を返す可能性があるためです。 また、エラー状態を通知する機能がありません。

`PQescapeString`は、一度に1接続のみで動作するシングルスレッドのクライアントプログラムでは安全に利用できます。 (この場合知らなければならない"裏側に隠された情報"を知ることができるからです。) 他の場合には、セキュリティ要因であり`PQescapeStringConn`を利用することで避けなければなりません。

## 30.3.5. SQLコマンドに含めるためのバイナリ文字列のエスケープ処理

`PQescapeByteaConn`

  --> `bytea`型としてSQLコマンド内で使用するバイナリデータをエスケープします。 `PQescapeStringConn`と同様、これは、SQLコマンド文字列にデータを直接含める場合にのみに使用されます。

              unsigned char *PQescapeByteaConn(PGconn *conn,
                                               const unsigned char *from,
                                               size_t from_length,
                                               size_t *to_length);

  SQL内の`bytea`リテラルの一部として使用する場合、特定のバイト値はエスケープされなければなりません。 (全てのバイト値をエスケープしても構いません。) 一般には、バイトをエスケープするには、通常2つのバックスラッシュの後に、その8進数値と等しくなる3桁の8進数に変換します。 単一引用符(`'`)とバックスラッシュ(`\`)は特別に他のエスケープ処理が行われます。 詳細は項8.4を参照してください。 `PQescapeByteaConn`は、最低限必要なバイトのみをエスケープすることで、この操作を行います。

  `from`パラメータはエスケープ対象の文字列の先頭バイトを指し示すポインタです。 `from_length`パラメータは、このバイナリ文字列内のバイト数を指定します。 (終端を表す1バイトのゼロは不要、かつ、数えられません。) `to_length`パラメータは結果となるエスケープされた文字列の長さを保持する変数へのポインタです。 この結果文字列長は、結果内の終端を表す1バイトのゼロを含みます。

  `PQescapeByteaConn`は、`from`パラメータが示すバイナリ文字列をエスケープしたものを`malloc()`で確保したメモリ内に返します。 その結果が不要になったら、このメモリを`PQfreemem`を使用して解放しなければなりません。 返される文字列では、PostgreSQLリテラル文字列パーサと`bytea`入力関数によって適切に処理できるように、全ての特殊な文字が置換されています。 終端を表す1バイトのゼロも追加されます。 PostgreSQLのリテラル文字列を括る単一引用符は結果文字列には含まれません。

  エラー時、NULLポインタを返し適切なエラーメッセージを`conn`オブジェクトに格納します。現在、唯一有り得るエラーは結果文字列のメモリ不足です。

`PQescapeBytea`

  `PQescapeBytea`は、`PQescapeByteaConn`の推奨されない古いものです。

              unsigned char *PQescapeBytea(const unsigned char *from,
                                           size_t from_length,
                                           size_t *to_length);

  `PQescapeBytea`の`PQescapeByteaConn`との唯一の違いは、`PGconn`パラメータです。 これは、`PQescapeBytea`が接続プロパティー(規格に適合する文字列であろうとなかろうと)による振舞を調整できないこと、そして間違った結果を返す可能性があるためです。 また、失敗のエラーメッセージを通知する機能はありません。

  `PQescapeBytea`は、一度に1接続のみで動作するシングルスレッドのクライアントプログラムでは安全に利用できます。 (この場合知らなければならない"裏側に隠された情報"を知ることができるからです。) 他の場合には、セキュリティ要因であり`PQescapeByteaConn`を利用することで避けなければなりません。

`PQunescapeBytea`

  バイナリデータの文字列表現をバイナリデータに変換します。 つまり、`PQescapeBytea`の逆です。 これは、`bytea`データをテキスト書式で受けとった場合に必要とされます。 しかし、バイナリ書式で受けとった場合は不要です。

              unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length);

  `from`パラメータは、例えば、`bytea`列に`PQgetvalue`を行なった場合に返される可能性がある、文字列を指し示すポインタです。 `PQunescapeBytea`は、この文字列表現をバイナリ表現に変換します。 `malloc()`で確保したバッファへのポインタを返します。 エラー時はNULLポインタです。 また、このバッファのサイズを`to_length`に格納します。 不要になったら、この結果を`PQfreemem`を使用して解放しなければなりません。

  この変換は、`PQescapeBytea`の逆ではありません。文字列は`PQgetvalue` から受け取る場合"エスケープされた"ことを予想しないためです。 特にこれは、文字列の引用符付けを意識する必要がなく、そのため`PGconn`パラメータを持つ必要がないことを意味します。

前のページ | ホーム | 次のページ
接続状態関数 | 上に戻る | 非同期コマンドの処理