karlley's tech blog

学習メモや記録とか

pg gem のexec系メソッドの使い分け

Sinatraのメモアプリでpg gemを使う機会がありました。 DBにSQLを実行するexec ~ 系のメソッドの選択に迷ったので調べてみました。

結論

execexec_paramsexec_prepared の3つのメソッドは次のように使い分ける。

よく分からなかった静的プレースホルダと動的プレースホルダについても調べました。

exec

PG: The Ruby PostgreSQL Driver

  • PostgreSQLSQLを発行する。
  • 返り値
    • 成功: 各レコードが入った配列型のPGオブジェクト
    • 失敗: PG::Error
  • 引数にparamsを指定した場合は自動でexec_params が呼ばれる。
  • プレースホルダーを使ってSQLを組み立てる場合は明示的にexec_params を使った方が良い。
  • execasync_execエイリアスsync_exec とほとんど同じ。

exec_params

PG: The Ruby PostgreSQL Driver

  • パラメータを使ったプレースホルダーで組み立てたSQLPostgreSQLに実行する。
  • 返り値
    • 成功: PG::Result(exec と同じ)
    • 失敗: PG::Error
  • 引数に型指定が可能(指定しない場合はPostgreSQLが自動で判断する)。
  • 返り値のフォーマットを指定可能(テキスト、バイナリ)。
  • SQLインジェクション対策が自動で行われる。
    • 引用符付け、エスケープが自動で行われる。
    • 引数の文字列の中で1つのSQLしか実行できない。
  • async_exec_paramsエイリアス

exec_prepared

PG: The Ruby PostgreSQL Driver

  • paramsを使って動的に組み立てたSQLPostgreSQLに実行する。
  • 返り値
    • 成功: PG::Result(execと同じ)
    • 失敗: PG::Error
  • 型、フォーマットの指定が可能(exec_paramsと同じ)
  • async_exec_preparedエイリアス

まとめ

使い分けが分かってスッキリしました。 今回のプラクティスではSQLインジェクションの対策が終了条件に含まれているのでexec_params を使って実装してみようと思います。

参照

安全なSQLの呼び出し方

PostgreSQLのバルクインサートをRubyからPrepared Statementで実行 - Qiita

バルクインサートとは - 意味をわかりやすく - IT用語辞典 e-Words

プリペアドステートメントとは - 意味をわかりやすく - IT用語辞典 e-Words