🙄
C++Builderでパラメータ化クエリを使用する
パラメータ化クエリとは
パラメータ化クエリとは、SQL文に直接値を埋め込むのではなく、プレースホルダ(? や :param_name など)を使い、後から値をバインド(割り当て)する方法のこと。
主な特徴
- SQL文の構造を固定し、データ部分のみを変化させる。
- SQLインジェクションを防ぐための有効な対策となる。
- データベースのパフォーマンスが向上する(特に同じクエリを繰り返し実行する場合)。
サンプルコード
void __fastcall TForm1::Button1Click(TObject *Sender)
{
std::unique_ptr<TFDConnection> Conn (new TFDConnection(NULL));
std::unique_ptr<TFDQuery> Qry (new TFDQuery(NULL));
Qry->Connection = Conn.get();
Conn->DriverName = "SQLite";
Conn->Params->Database = GetCurrentDir() + "\\MyDb.db";
// テーブル定義
Qry->SQL->Text =
"CREATE TABLE MYTABLE(NAME TEXT, AGE INTEGER, PRIMARY KEY(NAME))";
Qry->ExecSQL();
// パラメータ化クエリ (:NAMEと:AGEがプレースホルダとなり、後から値が代入可能)
Qry->SQL->Text =
" INSERT INTO MyTable (NAME, AGE) VALUES (:NAME, :AGE);";
Qry->ParamByName("NAME")->AsString = "SOUSEKI"; // :NAME置換 ※シングルコーテーション自動付与
Qry->ParamByName("AGE")->AsInteger = 49; // :AGE置換
Qry->ExecSQL();
}
その他
うれしい点
- SQL文の可読性が高くなる(SQL文が長いと特に)
- String型代入時にシングルコーテーションが自動付与(地味にうれしい)
- SQLインジェクションなどへのセキュリティが向上する
注意点
- プレースホルダの指定忘れがあってもエラーにならない
- 動的なSQL文の構築ではコードが煩雑になる
- プレースホルダの名称はフィールド名に一致させる必要はない
今までこんなことやってたんだぜ...
AnsiString myName = "SOUSEKI";
int age = 49;
Qry->SQL->Add("INSERT INTO MyTable (NAME, AGE) VALUES (";
Qry->SQL->Add(myName);
Qry->SQL->Add(",");
Qry->SQL->Add(age);
Qry->SQL->Add(")");
Qry->SQL->Add(";");
Discussion