いったんデータベースサーバへの接続の確立が成功すれば、この節で説明する関数を使って SQL の問い合わせやコマンドを実行します。
コマンド文字列には、(セミコロンで区切った)複数のSQLコマンドを含めることができます。 単一のPQexec呼び出しで送信された複数の問い合わせは単一トランザクションで処理されます。ただし、もし問い合わせ文字列内に明示的なBEGIN/COMMITがある場合は、複数のトランザクションに分離されます。 しかし、返されるPGresult構造体はその文字列内で最後に実行されたコマンドの結果のみが含まれることに注意してください。 そのコマンドの1つが失敗したとすると、文字列の処理はそこで中断し、エラー条件が含まれるPGresultが返されます。
サーバにコマンドを送信し、結果を待ちます。ただし、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で使用した場合は失敗します。
パラメータが使用された場合、それらはコマンド文字列内では$1や$2などとして参照されます。 nParamsは与えられるパラメータ数で、paramTypes[]、paramValues[]、paramLengths[]、paramFormats[]の配列要素数となります。 (nParamsが0の場合は、この配列へのポインタをNULLにしても構いません。) paramTypes[] は、パラメータシンボルに割り当てられたデータ型を、そのOIDで指定します。 paramTypes[] がNULL、もしくは、その配列の特定要素がゼロの場合、サーバは型指定がないリテラル文字列の扱いと同じ方法で、そのパラメータシンボルのデータ型を割り当てます。 paramValues[]はパラメータの実際の値を指定します。 この配列内のヌルポインタは、対応するパラメータがヌルであることを意味します。 これ以外の場合、ポインタはゼロ終端のテキスト文字列(テキスト書式の場合)、もしくは、サーバが想定している書式のバイナリデータ(バイナリ書式の場合)へのポインタとなります。 paramLengths[]はバイナリ書式パラメータの実際のデータ長を指定します。 ヌルパラメータやテキスト書式のパラメータの場合は無視されます。 この配列へのポインタは、バイナリパラメータが存在しない場合はヌルにしても構いません。 paramFormats[]は、パラメータがテキスト(配列に0を設定)かバイナリ(配列に1を設定)かを指定します。 この配列へのポインタがヌルの場合、すべてのパラメータはテキストであるとみなされます。 テキスト書式で結果を取り出す場合はresultFormatにゼロを設定します。 バイナリ書式の場合は1を設定します。 (現時点では、結果の異なる列を異なる書式で取り出す予定はありません。しかし、プロトコル内部では実現可能なものです。)
PQexecに対するPQexecParamsの主要な利点は、コマンド文字列とパラメータ値を分離可能である点です。 これにより、退屈でエラーを招きやすい引用符付けやエスケープ処理を行なう必要がなくなります。 PQexecと異なり、PQexecParamsは、文字列内に最大でも1つのSQLコマンドを入れることができます。 (セミコロンを入れることはできますが、空でないコマンドを1つ以上入れることはできません。) これは、プロトコル自体の制限ですが、SQL混入攻撃に対する追加の防御となる点より多少役に立ちます。
指定パラメータによる準備済の文の実行要求を送信し、結果を待ちます。
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[]パラメータは存在しません。 (準備済み文のパラメータ型はその作成時点で決定されているため、これは不要です。)
今の所、PQexecPreparedで使用される準備済み文は、PREPARE SQLコマンドを実行することで設定しなければなりません。 これは通常PQexecで送信されます。 (もちろんlibpqの他の問い合わせ送信関数を使用することができます。) 準備済み文に対するより低レベルのインタフェースを将来のリリースで提供する可能性があります。
PGresult構造体は、サーバから返された結果をカプセル化します。 libpqアプリケーションのプログラマは注意してPGresultという抽象化を維持してください。 以下のアクセス用関数を使用して、PGresultの内容を取り出してください。 将来の変更に影響されますので、PGresult構造体のフィールドを直接参照することは避けてください。
コマンドの結果状態を返します。
ExecStatusType PQresultStatus(const PGresult *res);
PQresultStatusは以下のいずれかの値を返します。
サーバに送信された文字列が空でした。
データを返さないコマンドが正常終了しました。
データを返すコマンド(SELECT や SHOWなど)が正常終了しました。
(サーバからの)コピーアウトデータ転送が始まりました。
(サーバへの)コピーインデータ転送が始まりました。
サーバが不明な応答を返しました。
致命的ではない(注意喚起もしくは警告)エラーが発生しました。
致命的なエラーが発生しました。
結果状態が PGRES_TUPLES_OK であれば、問い合わせが返した行を、以下で説明する関数を使って取り出すことができます。 ただし、たまたま SELECTコマンドが返す行が 0 個だったような場合でも PGRES_TUPLES_OK となることに注意してください。 PGRES_COMMAND_OKは、行を全く返さない(INSERT、UPDATEなどの)コマンド用です。 PGRES_EMPTY_QUERYという応答はクライアントソフトウェアの不具合を示しているかもしれません。
PGRES_NONFATAL_ERROR状態の場合、結果はPQexecや他の問い合わせ実行関数によって直接返されません。 その代わりに、この種の結果は注意喚起処理器(項27.9参照)に渡されます。
PQresultStatus が返す列挙型から状態コードを説明する文字列定数に変換します。
char *PQresStatus(ExecStatusType status);
コマンドに関するエラーメッセージを返します。 エラーが何もなければ、空の文字列を返します。
char *PQresultErrorMessage(const PGresult *res);
エラーがあった場合、返される文字列には改行が含まれます。
(接続に対する)PQerrorMessage も、PQexec または PQgetResult 呼び出しの直後なら (結果に対する)PQresultErrorMessageと同じ文字列を返します。 しかし、接続に対するエラーメッセージは後続する操作を実行すると変化してしまうのに対し、PGresult はオブジェクトが破棄されるまでそのエラーメッセージを維持し続けます。 この PQresultErrorMessage は個々の PGresult に結び付けられた状態を見る時に、そして PQerrorMessage は接続における最後の操作の状態を見る時に使用してください。
エラー報告の個々のフィールドを返します。
char *PQresultErrorField(const PGresult *res, int fieldcode);
fieldcodeはエラーフィールド識別子です。 以下に示すシンボルを参照してください。 PGresultがエラーではない、もしくは、警告付きの結果である場合や指定したフィールドを含まない場合、NULLが返されます。 通常フィールド値には改行が含まれません。
以下のフィールドコードが使用できます。
深刻度。 このフィールドの内容は (エラーメッセージの場合)ERROR、FATAL、もしくは、PANIC、(注意喚起メッセージの場合)WARNING、NOTICE、DEBUG、INFO、もしくは、LOGです。 これらは、多言語化により翻訳化されている可能性があります。 常に存在します。
エラーのSQLSTATEコードです。 (付録Aを参照してください。) 多言語化されません。 常に存在します。
主に可読性を高めたエラーメッセージです。 (通常は1行です。) 常に存在します。
詳細です。 問題に関するより詳細を表す補助的なエラーメッセージです。 複数行に跨る可能性があります。
ヒントです。 問題の対応方法についての補助的な提言です。 これは、詳細(detail)とは異なり、問題の事象ではなく、(適切でない可能性がありますが)アドバイスを提供することを目的としています。 複数行に跨る可能性があります。
元の問い合わせ文字列のインデックスとなるエラーが発生したカーソル一を示す10進整数を持つ文字列です。 先頭文字がインデックス1となり、また、バイトではなく、文字数で数えた位置です。
エラーが発生した文脈を示すものです。 今の所、これは活動中のPL関数の呼び出しスタックの追跡情報が含まれます。 この追跡は行単位で1項目であり、その順番は呼び出し順の反対になります。
エラーが報告された場所のソースコードのファイル名です。
エラーが報告された場所のソースコードにおける行番号です。
エラーを報告した、ソースコードにおける関数名です。
必要に応じた表示される情報の整形はクライアントの責任です。 具体的には、必要に応じて長い行を分割します。 エラーメッセージフィールド内の改行文字は、改行としてではなく段落として分かれたものとして取扱うべきです。
libpqで内部的に生成されたエラーは、深刻度と主要メッセージを持ちますが、通常は他のフィールドを持ちません。 3.0より前のプロトコルのサーバで返されるエラーは、深刻度と主要メッセージ、場合によって詳細メッセージを持ちますが、他のフィールドを持ちません。
エラーフィールドはPGresultからのみ利用でき、PGconnからは利用できません。 PQerrorFieldという関数はありません。
PGresult に割り当てられた記憶領域を解放します。 個々の問い合わせ結果は、必要なくなった時に PQclearで解放するべきです。
void PQclear(PQresult *res);
PGresult オブジェクトは、必要な間保持することができます。 新しい問い合わせを発行する場合でも、接続を閉じてしまうまでは PGresult は消えません。 PGresult を解放するには、PQclearを呼び出さなくてはいけません。 その操作に失敗してしまうと、アプリケーションのメモリリークを引き起こしてしまいます。
与えられた状態を持った、空の PGresult オブジェクトを生成します。
PGresult* PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status);
空のPGresult オブジェクトを割り当て、初期化する、libpqの内部関数です。 一部のアプリケーションでは、それ自身でPGresultオブジェクト(特にエラーステータスを含めたオブジェクト)を生成できると便利なのでこの関数はエクスポートされています。 conn がヌルで なく、statusがエラーを示している場合、接続の現在のエラーメッセージが PGresult にコピーされます。 なお、libpq 自体が返す PGresult と同じように、最後に PQclear をこのオブジェクトに対して呼び出さなければならないことに注意してください。
これらの関数を使用して、正常終了した問い合わせ結果を示す(つまり、その状態がPGRES_TUPLES_OKとなっている)PGresultオブジェクトから情報を抽出することができます。 他の状態値を持つオブジェクトでは、これらの関数は、結果が0行0列であるものと同様に動作します。
問い合わせ結果内の行(タプル)数を返します。
int PQntuples(const PGresult *res);
問い合わせ結果の各行の列(フィールド)の数を返します。
int PQnfields(const PGresult *res);
指定した列番号に対応する列の名前を返します。 列番号は0から始まります。
char *PQfname(const PGresult *res, int column_number);
列番号が範囲外であった場合、NULL が返ります。
指定した列名に対応する列番号を返します。
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
指定した列の抽出元であるテーブルのOIDを返します。
Oid PQftable(const PGresult *res, int column_number);
列番号が範囲外の場合や指定した列がテーブル列への単純な参照でない場合、3.0より前のプロトコルを使用している場合は、InvalidOidが返されます。 pg_classシステムテーブルに問い合わせ、どのテーブルが参照されているのかを正確に求めることができます。
libpqヘッダファイルをインクルードすると、Oid 型とInvalidOid定数が定義されます。 これらは両方とも何らかの整数型です。
指定した問い合わせ結果の列を作成した列の(それが属するテーブル内での)列番号を返します。 結果の列番号は0から始まります。
int PQftablecol(const PGresult *res, int column_number);
列番号が範囲外の場合や指定した列がテーブル列への単純な参照でなかった場合、3.0より前のプロトコルを使用している場合は、ゼロが返されます。
指定した列の書式を示す書式コードが返ります。 列番号は0から始まります。
int PQfformat(const PGresult *res, int column_number);
ゼロという書式コードはテキストデータ表現を示し、1という書式コードはバイナリ表現を示します。 (他のコードは将来の定義のために予約されています。)
指定した列番号に関連したデータ型を返します。 返された整数は、その型の内部的なOID番号です。 列番号は0から始まります。
Oid PQftype(const PGresult *res, int column_number);
pg_typeシステムテーブルに問い合わせて、各種データ型の名前や属性を得ることができます。 組み込みデータ型のOIDは、ソースツリー内のsrc/include/catalog/pg_type.hファイル内で定義されています。
指定した列番号に関連した列の型修飾子を返します。 列番号は0から始まります。
int PQfmod(const PGresult *res, int column_number);
修飾子の値の解釈は型に固有なものです。 通常、これらは精度やサイズの制限を示します。 -1という値は"使用できる情報がない"ことを示します。 ほとんどのデータ型は修飾子を使用しません。この場合は常に-1という値になります。
指定した列番号に関連した列のバイト単位のサイズを返します。 列番号は0から始まります。
int PQfsize(const PGresult *res, int column_number);
PQfsizeはデータベース行内でその列用に割り当てられる領域を返します。 言い替えると、そのデータ型についてのサーバでの内部表現のサイズです。 (従って、実際にはクライアントから見るとあまり役には立ちません。) 負の値は可変長データ型を示します。
PGresultがバイナリデータを持つ場合は1を、テキストデータを持つ場合は0を返します。
int PQbinaryTuples(const PGresult *res);
この関数は廃れたものです。 (COPYを行なう接続での使用を除きます。) 単一のPGresultで、ある列はテキストデータを持ち、他の列ではバイナリデータを持つことが可能であるためです。 PQfformatをお勧めします。 PQbinaryTuplesは、結果のすべての列がバイナリ(書式1)の場合にのみ1を返します。
PGresultの1行における単一フィールドの値を返します。 行番号と列番号は0から始まります。
char* PQgetvalue(const PGresult *res, int row_number, int column_number);
テキスト書式のデータでは、PQgetvalueで返される値はフィールド値をヌル終端の文字列表現となります。 バイナリ書式のデータでは、この値はデータ型のtypsend 関数とtypreceive 関数で決まるバイナリ表現となります。 (実際にはこの場合でも値の終りにゼロというバイトが付与されます。しかし、この値の内部には大抵の場合ヌルが埋め込まれていますので、通常このバイトは有用ではありません。)
フィールド値がNULLの場合、空文字列が返されます。 NULL値と空文字列という値とを区別する方法はPQgetisnullを参照してください。
PQgetvalueによって返されるポインタは、PGresult構造体の一部の格納領域を指し示します。 このポインタが指し示すデータを変更すべきではありません。また、PGresult構造体を解放した後も使用し続ける場合はデータを別の格納領域に明示的にコピーしなければなりません。
フィールドがNULL値かどうか検査します。 行番号と列番号は0から始まります。
int PQgetisnull(const PGresult *res, int row_number, int column_number);
この関数は、フィールドがNULLの場合に1を、フィールドが非NULL値を持つ場合は0を返します。 (PQgetvalueでは、NULLフィールドはヌルポインタではなく空文字列を返すことに注意してください。)
実際のフィールド値の長さをバイト単位で返します。 行番号と列番号は0から始まります。
int PQgetlength(const PGresult *res, int row_number, int column_number);
これは、特定のデータ値についての実際のデータ長です。 つまり、PQgetvalueによって指し示されるオブジェクトのサイズです。 テキストデータ書式では、strlen()と同一です。 バイナリ書式では、これは重要な情報です。 実際のデータ長を取り出すためにPQfsizeを信用してはなりません。
すべての行と列名(省略可能)を指定した出力ストリームに表示します。
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; /* フィールド名を置き換えるヌル終端の配列 */ } PQprintOpt;
この関数は以前問い合わせ結果を表示するためにpsqlで使用されていましたが、今ではもう使用されていません。 これはすべてのデータがテキスト書式であるという前提で動作することに注意してください。
これらの関数はSELECT結果以外のPGresultオブジェクトから情報を取り出すために使用されます。
PGresultを生成したSQLコマンドのコマンド状態タグを返します。
char * PQcmdStatus(PGresult *res);
一般的に、これは単なるコマンドの名前になります。 しかし、処理対象行数など追加的な情報が含まれる場合があります。
SQLコマンドで影響を受けた行数を返します。
char * PQcmdTuples(PGresult *res);
PGresultを生成したSQLコマンドがINSERT、UPDATE、DELETE、MOVE、FETCHであった場合、これは影響を受けた行数を持つ文字列を返します。 この他のコマンドの場合、空文字列を返します。
SQLコマンドが、OIDを持つテーブル内に1行のみを挿入するINSERTだった場合、挿入された行のOIDを返します。 さもなくばInvalidOidを返します。
Oid PQoidValue(const PGresult *res);
SQLコマンドがINSERTであった場合、挿入された行のOIDを文字列で返します。 (INSERTが複数行を挿入した場合や対象テーブルがOIDを持たない場合は、0という文字列を返します。) コマンドがINSERTでなければ、空文字列を返します。
char * PQoidStatus(const PGresult *res);
この関数はPQoidValueのために廃れたものになりました。 これはスレッドセーフではありません。
PQescapeStringは、SQLコマンド内で使用するために文字列をエスケープします。 これは、SQLコマンド内のリテラル定数としてデータ値を挿入する時に有用です。 特定の文字(引用符やバックスラッシュ)は、SQLパーサによって特殊な解釈がなされないようにエスケープされなければなりません。 PQescapeStringはこの操作を行ないます。
ティップ: 信用できない入力元から受けとった文字列を扱う場合に適切なエスケープ処理を行なうことは非常に重要です。 さもなくば、セキュリティ上の危険性が発生します。 "SQL混入"攻撃という弱点となり、好ましくないSQLコマンドがデータベースに流れてしまいます。
PQexecParamsやその派生ルーチンを使用して分離されたパラメータとしてデータ値を渡す場合は、エスケープ処理は必要がなく、また、不正確になることに注意してください。
size_t PQescapeString (char *to, const char *from, size_t length);
fromパラメータは、エスケープ対象の文字列の先頭を指すポインタです。 lengthパラメータはこの文字列の文字数を示します。 ゼロバイトによる終端は必要なく、また、lenthではこれを数えてはなりません。 (もしlengthバイト処理する前に終端を表す1バイトのゼロが存在すると、PQescapeStringはそのゼロで終了します。この動作はstrncpyと同様です。) to は、最低でもlength の2倍よりも1文字多い文字を保持可能なバッファへのポインタにしなければなりません。 さもないと、動作は不定になります。 PQescapeStringを呼び出すと、from文字列を特殊な文字を害が起こらないように置き換えて、終端を表す1バイトのゼロを加えることで、エスケープしたものをtoバッファに書き出します。 結果文字列には、PostgreSQLのリテラル文字列を括るための単一引用符は含まれません。 これは、結果をSQLコマンドに挿入する時に付与しなければなりません。
PQescapeStringはtoに書き出した文字数を返します。 ただし、文字数には終端を表す1バイトのゼロは含まれません。
toとfrom文字列の領域が重なる場合の動作は不定です。
bytea型としてSQLコマンド内で使用するバイナリデータをエスケープします。 PQescapeStringと同様、 これは、SQLコマンド文字列にデータを直接含める場合にのみに使用されます。
unsigned char *PQescapeBytea(const unsigned char *from, size_t from_length, size_t *to_length);
SQL内のbyteaリテラルの一部として使用する場合、特定のバイト値はエスケープされなければなりません。 (すべてのバイト値をエスケープしても構いません。) 一般には、バイトをエスケープするには、2つのバックスラッシュの後に、その8進数値と等しくなる3桁の8進数に変換します。 単一引用符(') とバックスラッシュ(\) は特別に他のエスケープ処理が行なわれます。 詳細は項8.4を参照してください。 PQescapeByteaは、最低限必要なバイトのみをエスケープすることで、この操作を行ないます。
fromパラメータはエスケープ対象の文字列の先頭バイトを指し示すポインタです。 from_lengthパラメータは、このバイナリ文字列内のバイト数を指定します。 (終端を表す1バイトのゼロは不要、かつ、数えられません。) to_lengthパラメータは結果となるエスケープされた文字列の長さを保持する変数へのポインタです。 結果文字列長は、結果内の終端を表す1バイトのゼロを含みます。
PQescapeByteaは、 fromパラメータが示すバイナリ文字列をエスケープしたものをmalloc()で確保したメモリ内に返します。 その結果が不要になったら、このメモリをPQfreememを使用して解放しなければなりません。 返される文字列では、PostgreSQL リテラル文字列パーサとbytea入力関数によって適切に処理できるように、すべての特殊な文字が置換されています。 終端を表す1バイトのゼロも追加されます。 PostgreSQLのリテラル文字列を括る単一引用符は結果文字列には含まれません。
バイナリデータをエスケープした文字列表現をバイナリデータに変換します。 つまり、PQescapeByteaの逆です。 これは、byteaデータをテキスト書式で受けとった場合に必要とされます。 しかし、バイナリ書式で受けとった場合は不要です。
unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length);
fromパラメータは、例えば、bytea列にPQgetvalueを行なった場合に返される可能性がある、エスケープされた文字列を指し示すポインタです。 PQunescapeByteaは、この文字列表現をバイナリ表現に変換します。 malloc()で確保したバッファへのポインタを返します。 エラー時はヌルポインタです。 また、このバッファのサイズをto_lengthに格納します。 不要になったら、この結果をPQfreememを使用して解放しなければなりません。
libpqで確保したメモリを解放します。
void PQfreemem(void *ptr);
libpq、具体的には、PQescapeBytea、PQunescapeBytea、PQnotifiesで確保されたメモリを解放します。 これは、マルチスレッド化DLL(VC6では/MD)を使用しない限りDLLを越えてメモリを解放することができない、Microsoft Windowsでは必要です。 他のプラットフォームでは、この関数はfree()標準ライブラリ関数と同一です。