無料スクリプト配布のPHP.TO   PHPの実用的なtips PHPマニュアル MySQLマニュアル Apacheマニュアル PostgreSQLマニュアル マニュアル検索    

31.3. コマンド実行関数

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

31.3.1. 主要な関数

PQexec

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

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

戻り値は PGresult へのポインタ、場合によってはヌルポインタです。 メモリ不足の状態、あるいはサーバへのコマンド送信が不可能といった深刻なエラーの場合を除けば、通常非ヌルのポインタが返ります。 PQresultStatus 関数を呼び出して、何かエラー(ヌルポインタ値を含むエラー。この場合は 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であることを意味します。 さもなくば、このポインタはゼロ終端のテキスト文字列(テキスト書式)、または、サーバで想定している書式によるバイナリデータ(バイナリ書式)を指し示します。

paramLengths[]

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

paramFormats[]

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

バイナリ書式で渡された値は、バックエンドが想定する内部表現の知識を必要とします。 例えば、整数はネットワークバイト順に渡されなければなりません。 numeric による値は、 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 オブジェクトで、その内容でサーバ側の成功や失敗を示します。 ヌルという結果はメモリ不足や全くコマンドを送信することができなかったことを示します。 こうしたエラーの詳細情報を入手するには PQerrorMessage を使用してください。

PQexecPrepared で使用するためのプリペアド文は、 PREPARE SQL文を実行することでも作成可能です。 また、プリペアド文を削除する libpq 関数はありませんが、この目的のために DEALLOCATE SQL文を使用することができます。

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_COPY_BOTH

(サーバからおよびサーバへの)コピーイン/アウトデータ転送が始まりました。 現在こればストリーミングレプリケーションのみで使用されます。 このためこの状態は通常のアプリケーションでは起こりません。

PGRES_SINGLE_TUPLE

PGresult には現在のコマンドからの結果タプルが1つ含まれます。 この状態は問い合わせで単一行モードが選択された場合( 項31.5 参照)のみ起こります。

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

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

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_SCHEMA_NAME

もしそのエラーが特定のデータベースオブジェクトに付随する時、もしあれば、そのオブジェクトを含むスキーマ名です。

PG_DIAG_TABLE_NAME

もしそのエラーが特定のテーブルに付随する時のテーブル名です。(テーブルのスキーマ名についてはスキーマ名フィールドを参照ください。)

PG_DIAG_COLUMN_NAME

もしそのエラーが特定のテーブル列に付随する時の列名です。(テーブルを識別するにはスキーマとテーブル名フィールドを参照ください。)

PG_DIAG_DATATYPE_NAME

もしそのエラーが特定のデータ型に付随する時のデータ型名です。(データ型のスキーマ名についてはスキーマ名フィールドを参照ください。)

PG_DIAG_CONSTRAINT_NAME

もしそのエラーが特定の制約に付随する時の制約名です。 付随するテーブルまたはドメインについては上記にリストされたフィールドを参照ください。 (この目的のために、制約は制約構文で作成されていなくてもインデックスは制約として扱われます。)

PG_DIAG_SOURCE_FILE

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

PG_DIAG_SOURCE_LINE

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

PG_DIAG_SOURCE_FUNCTION

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

注意: スキーマ名、テーブル名、列名、データ型名、および制約名に対するフィールドは限定的なエラー型に対してのみ提供されます。 付録A を参照ください。 これらのフィールドのいかなる存在もその他のフィールドの存在を保証すると推測してはなりません。 コアエラーの出所は上に記載の相互関係を監視しますが、ユーザ定義関数はこれらフィールドを別目的で使用しているかもしれません。 同様の脈絡で、使用しているデータベースで これらのフィールドが同時に存在するオブジェクトを意味すると推測してはなりません。

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

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

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

PQclear

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

void PQclear(PGresult *res);

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

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

これらの関数を使用して、正常終了した問い合わせ結果を示す(つまり、その状態が PGRES_TUPLES_OK または PGRES_SINGLE_TUPLE となっている) 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 で返される値はフィールド値をヌル終端の文字列表現となります。 バイナリ書式のデータでは、この値はデータ型の typsend 関数と typreceive 関数で決まるバイナリ表現となります。 (実際にはこの場合でも値の終わりにゼロというバイトが付与されます。 しかし、この値の内部には大抵の場合ヌルが埋め込まれていますので、通常このバイトは有用ではありません。)

フィールド値が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フィールドはヌルポインタではなく空文字列を返すことに注意してください。)

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 で使用されていましたが、今ではもう使用されていません。 これはすべてのデータがテキスト書式であるという前提で動作することに注意してください。

31.3.3. 他の結果情報の取り出し

これらの関数は PGresult オブジェクトからその他の情報を取り出すために使用されます。

PQcmdStatus

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

char *PQcmdStatus(PGresult *res);

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

PQcmdTuples

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

char *PQcmdTuples(PGresult *res);

この関数は PGresult を生成した SQL コマンドにより影響を受けた行数を持つ文字列を返します。 この関数は SELECT CREATE TABLE AS 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

この関数は PQoidValue のため廃止予定になりました。 またこれはスレッドセーフではありません。 これは挿入された行のOIDを文字列として返します。 一方 PQoidValue はOID値を返します。

char *PQoidStatus(const PGresult *res);

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

PQescapeLiteral

char *PQescapeLiteral(PGconn *conn, const char *str, size_t length);

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

PQescapeLiteral str パラメータをエスケープしたものを malloc() で割り当てたメモリ内に返します。 その結果が不要になったら、そのメモリを PQfreemem() を使用して解放しなければなりません。 ゼロバイト終端は必要なく、 length に含めて数えてはいけません。 ( length バイトを処理する前にゼロバイト終端が見つかると、 PQescapeLiteral はそのゼロで終了します。 この動作は strncpy と似ています。) 返される文字列では、 PostgreSQL 文字列リテラルパーサで適切に処理することができるように、すべての特殊文字は置換されます。 ゼロバイト終端も追加されます。 PostgreSQL の文字列リテラルでは前後に必要となる単一引用符も、その結果文字列には含まれています。

エラー時、 PQescapeLiteral NULL を返し、 conn オブジェクト内に適切なメッセージを残します。

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

データが PQexecParams または同義のルーチン内で別のパラメータとしてデータ値が渡される場合は、エスケープする必要も修正することもないことに注意してください。

PQescapeIdentifier

char *PQescapeIdentifier(PGconn *conn, const char *str, size_t length);

PQescapeIdentifier は、テーブル、列、関数名などのSQL識別子として使用できるように文字列をエスケープします。 これはユーザが提供した識別子に、そのままではSQLパーサで識別子として解釈されない特殊な文字が含まれる可能性がある場合、または、大文字小文字の違いを維持しなければならない状況で識別子に大文字が含まれる可能性がある場合に有用です。

PQescapeIdentifier str パラメータをSQL識別子としてエスケープしたものを malloc() で割り当てたメモリ内に返します。 その結果が不要になったら、そのメモリを PQfreemem() を使用して解放しなければなりません。 ゼロバイト終端は必要なく、 length に含めて数えてはいけません。 ( length バイトを処理する前にゼロバイト終端が見つかると、 PQescapeIdentifier はそのゼロで終了します。 この動作は strncpy と似ています。) 返される文字列では、SQL識別子として適切に処理することができるように、すべての特殊文字は置換されます。 ゼロバイト終端も追加されます。 その結果文字列の前後には二重引用符が付与されます。

エラー時、 PQescapeIdentifier NULL を返し、 conn オブジェクト内に適切なメッセージを残します。

ティップ: 文字列リテラルと同様、SQLインジェクション攻撃を防ぐために、信頼できない入力元から受けとる場合にはSQL識別子をエスケープしなければなりません。

PQescapeStringConn

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

PQescapeStringConn は、 PQescapeLiteral とほぼ同様に文字列リテラルをエスケープします。 PQescapeLiteral とは異なり、呼び出し元が適切な大きさのバッファを提供することに責任を持ちます。 さらに PQescapeStringConn PostgreSQL の文字リテラルとして囲まれなければならない単一引用符を生成しません。 これは、結果をSQLコマンドに挿入するときに付与しなければなりません。 from パラメータはエスケープ対象の文字列の先頭を指すポインタです。 length パラメータはこの文字列のバイト数を示します。 ゼロバイト終端は必要なく、また、 lenth ではこれを数えてはなりません。 (もし length バイト処理する前にゼロバイト終端が存在すると、 PQescapeStringConn はそのゼロで終了します。 この動作は strncpy と同様です。) to は、最低でも length の2倍よりも1バイト多い文字を保持可能なバッファへのポインタにしなければなりません。 さもないと、動作は不定になります。 to from 文字領域が重なる場合の動作も不定です。

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

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

PQescapeString

PQescapeString PQescapeStringConn の推奨されない古いものです。

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

PQescapeStringConn との唯一の違いは、 PQescapeString PGconn error パラメータを取らないことです。 このため(文字符号化方式のような)接続属性に依存する振舞いを調整できません。 その結果 間違った結果を返す可能性があります 。 また、エラー状態を通知する機能がありません。

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

PQescapeByteaConn

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

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

SQL 文内の bytea リテラルの一部として使用する場合、特定のバイト値はエスケープされなければなりません。 PQescapeByteaConn は16進数符号化またはバックスラッシュエスケープ処理を使用してバイトをエスケープします。 詳しくは 項8.4 を参照してください。

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

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

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

PQescapeBytea

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

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

PQescapeBytea PQescapeByteaConn との唯一の違いは、 PGconn パラメータです。 このため PQescapeBytea は、一度に1つの PostgreSQL 接続を使用するクライアントプログラムのみで安全に利用することができます。 (この場合知らなければならない "裏側に隠された情報" を知ることができるからです。) 複数のデータベース接続を使用するプログラムでは 間違った結果を返す可能性があります 。 (このような場合は 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 パラメータを持つ必要がないことを意味します。


powered by SEO.CUG.NET