Sinatraのメモアプリでpg gemを使う機会がありました。
DBにSQLを実行するexec ~
系のメソッドの選択に迷ったので調べてみました。
結論
exec
、exec_params
、exec_prepared
の3つのメソッドは次のように使い分ける。
exec
: 単純にSQLを実行したい。exec_params
: 動的プレースホルダで組み立てたSQLを実行したい。exec_prepared
: 静的プレースホルダ(Prepared Statment)で組み立てたSQLを実行したい。
よく分からなかった静的プレースホルダと動的プレースホルダについても調べました。
exec
PG: The Ruby PostgreSQL Driver
- PostgreSQLにSQLを発行する。
- 返り値
- 成功: 各レコードが入った配列型のPGオブジェクト
- 失敗: PG::Error
- 引数にparamsを指定した場合は自動で
exec_params
が呼ばれる。 - プレースホルダーを使ってSQLを組み立てる場合は明示的に
exec_params
を使った方が良い。 exec
はasync_exec
のエイリアスでsync_exec
とほとんど同じ。
exec_params
PG: The Ruby PostgreSQL Driver
- パラメータを使ったプレースホルダーで組み立てたSQLをPostgreSQLに実行する。
- 返り値
- 成功: PG::Result(
exec
と同じ) - 失敗: PG::Error
- 成功: PG::Result(
- 引数に型指定が可能(指定しない場合はPostgreSQLが自動で判断する)。
- 返り値のフォーマットを指定可能(テキスト、バイナリ)。
- SQLインジェクション対策が自動で行われる。
async_exec_params
のエイリアス
exec_prepared
PG: The Ruby PostgreSQL Driver
- paramsを使って動的に組み立てたSQLをPostgreSQLに実行する。
- 返り値
- 成功: PG::Result(
exec
と同じ) - 失敗: PG::Error
- 成功: PG::Result(
- 型、フォーマットの指定が可能(
exec_params
と同じ) async_exec_prepared
のエイリアス
まとめ
使い分けが分かってスッキリしました。
今回のプラクティスではSQLインジェクションの対策が終了条件に含まれているのでexec_params
を使って実装してみようと思います。
参照
PostgreSQLのバルクインサートをRubyからPrepared Statementで実行 - Qiita