2021-03-13 23:35:17
Elixir Ecto.Adapters.SQL.Query で名前付きでバインドしたいので NamedBindSql というモジュール作ってみた
Elixir Ecto.Adapters.SQL.Query で名前付きでバインドしたいので NamedBindSql というモジュール作ってみた
生SQLを使いたい
個人的にSQLは生SQLを使いたい派です。理由は最初に業務でSQLを書き始めたときにORMではなく、生SQLで書いたからです。生SQLといってもSQLインジェクション対策されたフレームワークの機能を利用しています。
Elixir Phoenix で生SQLを使う際ときは Ecto.Adapters.SQL.Query
を使用します。値をバインドするときは $1
をのように記載し、リストで値を設定します。
例えば以下のようにSQLを用意します。
"SELECT * FROM table1 AS t1 WHERE t1.id = $1 AND t1.hoge_id2 = $2 AND t1.id = $1 ;"
そして、 $1
, $2
には以下のように数値の順番を考慮してリストを用意します。
[1000, 2000]
順番を考慮したくない
:sample
のように名前をつけて値をバインドしたい。
:sample
=> $1
のように変換するモジュールを作ってみました
ので、NamedBindSql というモジュールを作ってみました。名前もうちょっとどうにかしたかった。
以下を入力とすると、
sql = "SELECT * FROM table1 AS t1 WHERE t1.id = :id AND t1.t2_id = :t2_id AND t1.id = :id;"
params = %{":id" => 1000, ":t2_id" => 2000}
以下を出力します
{
"SELECT * FROM table1 AS t1 WHERE t1.id = $1 AND t1.t2_id = $2 AND t1.id = $1 ;",
[1000, 2000]
}
全体的に以下のような使い方を想定しています。
sql = "SELECT * FROM table1 AS t1 WHERE t1.id = :id AND t1.t2_id = :t2_id AND t1.id = :id;"
params = %{":id" => 1000, ":t2_id" => 2000}
{sql_doller, param_list} = NamedBindSql.prepare_sql_with_params(sql, params)
Ecto.Adapters.SQL.Query(Yourapp.Repo, sql_doller, param_list)