これを処理する方法は2つあります。 1つ目は、値が挿入された文字列を準備することです。 2つ目は、値を個別に置き換えることができるクエリパラメータを使用することです。
最初の方法では、snprintf などの関数を使用できます。 サーバーに送信するコマンドを準備します。例:
char buffer[512];
int num=snprintf(buffer, sizeof(buffer),
"SELECT name FROM MYTABLE WHERE id=%d", id);
if (num>sizeof(buffer)) {
/* error: buffer was too small */
}
このバッファの後に、変数IDの実際の値を含むSQLクエリが含まれます。
snprintfからの戻り値をチェックして、バッファがオーバーフローしたかどうかを確認する必要があることに注意してください。
また、文字列をコマンドに配置するときは、文字列に引用符やその他の特殊文字が含まれていないことを確認する必要があることに注意してください。文字列がプログラムの外部から来ている場合、例えば。ユーザー入力から、それを適切に引用しないと、誰かが悪意のあるSQLを挿入する可能性のある大きな穴が残ります。 libpqは、PQescapeLiteral> このための機能。
ほとんどの場合に推奨されるもう1つの方法は、SQLコマンドとパラメーターを別々にサーバーに渡すことです。たとえば、PQexecParamsを使用してこれを行うことができます。 libpq関数。 SQL文字列は次のようになります:
PGresult r = PQexecParams(conn, /* Connection to database */
"SELECT name FROM mytable WHERE id=$1",
1, /* Number of parameters */
NULL, /* NULL means server should figure out the parameter types */
params, /* Pointer to array of strings containing parameters */
NULL, /* Not needed unless binary format used */
NULL, /* Not needed unless binary format used */
0 /* Result to come back in text format */
);
この関数を使用すると、パラメータを指定したり、テキスト形式またはバイナリ形式で結果を取得したりできます。簡単にするために、上記の例では両方のテキスト形式を想定しています。
これのバリエーションは、プリペアドステートメントを使用することです。この場合、libpqを2回別々に呼び出します。
-
上記の例のように、パラメーター値$ 1、$2などを指定してSQLステートメントを渡すPQprepareを呼び出します。これにより、ステートメントハンドルが返されます。
-
PQexecParamsと同様の方法で指定された、ステートメントハンドルとパラメータ自体を渡すPQexecPreparedを呼び出します。
このような2つの手順を使用する利点は、ステートメントを1回準備し、それを何度も実行できることです。これにより、ステートメントの解析とクエリの計画に関連するサーバーのオーバーヘッドが削減されます。