🙄

C++Builderでパラメータ化クエリを使用する

2025/03/02に公開

パラメータ化クエリとは

パラメータ化クエリとは、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