悩んでいたこと
- IN句で複数の条件を指定したい
- INSERT文で複数レコード登録したい
これらはただSQL文を書くのは簡単ですが、プレースホルダーを使った上での書き方が難しく、日本語の情報が全くなかったので、まとめました。
上記以外に使えそうな記法もまとめてあります。
前提
pg-promiseパッケージを使用し、databaseとの接続などはできていることとします。
載せているサンプルコードではanyメソッドを使っていますが、非推奨なので、oneやmanyを適宜使いましょう。
普通のSELECT文
とりあえず、例としてただのSELECT文
constuserName='田中';constquery='SELECT * FROM user WHERE name = $1';constres=awaitdb.any(query,[userName]);
クエリ内の"$1"がanyメソッドの第二引数の値で置き換わる感じです。
IN句に複数条件
constuserName=['田中','山田'];constquery='SELECT * FROM user WHERE name IN ($1:csv)';constres=awaitdb.any(query,[userName]);
":csv"というフォーマットを指定すると、配列がカンマ区切りで展開されます。
constuserName=['田中','山田'];constage=20;constquery='SELECT * FROM user WHERE name IN ($1:csv) AND age = $2';constres=awaitdb.any(query,[userName,age]);
他にもプレースホルダーを使いたい場合もそのまま書けます。
複数レコードINSERT
constuserName=['田中','山田'];constquery=pgp.helpers.insert(userName,['name'],'user');constres=awaitdb.any(query);
pgpヘルパーを利用して解決しました。
以下のような書き方もできます。
ColumnSetインスタンスは再利用可能であり、パフォーマンス面からも推奨されます。
constuserName=['田中','山田'];constcs=newpgp.helpers.ColumnSet(['name'],{table:'user'});constquery=pgp.helpers.insert(userName,cs);constres=awaitdb.any(query);
INSERTしたレコードのIDを取得する
userテーブルには自動採番されるid列があるとします。
constuserName=['田中','山田'];constquery=pgp.helpers.insert(userName,['name'],'user')+'RETURNING id';constres=awaitdb.any(query);
resには[{id: '1'}, {id: '2'}]が入っています。
mapメソッドを使えばもっと便利なことができます。
constuserName=['田中','山田'];constquery=pgp.helpers.insert(userName,['user-name'],'user')+'RETURNING id';constres=awaitdb.map(query,[],r=>+r.id);
resには[1, 2]が入っています。
まとめ
他にもいろいろ便利なものがありそうですが、とりあえず困っていることは解決できたので、ここまでにします。
参考
pg-promise公式ヘルパーページ
pg-promise公式フォーマットページ
Multi-row insert with pg-promise