突破ファイルおもしろいよね。
さてさて、タイトルの通り、postgresqlのプレースホルダ、つまりバインドできるパラメータの数には上限がある。
32767、らしい。覚えてらんね。
大体32000くらいとしか認識してないし、そんな認識で十分。
で、そんなクエリ作る方が悪いとか、
そんな検索許容させちゃ駄目だとか、色々思うところはあったとしても、
メンバーとして参画したら、客からの要望は既に固まっているし、なんなら設計終わっている。
DBのテーブル構造だってもう決まっている。
何が言いたいかというと、
IN句に何万件もの値を渡して検索しなければならない機能
を作らなければならない!
っていう状況にたまに直面する。(2度目)
さて、じゃあどうするかというと、
・クライアントからはそのままListとして渡す。
・APIはこれを受け取り、'001', '002', '003', '004'...という1つの文字列とする。
・クエリのIN句には上記の文字列をバインドする。
これで1つで済む。
今の現場はORマッパーにmyBatisを使っているので、以下はその実装メモ。
■IN句に何万件も渡すと死ぬやつ
WHERE id IN
<foreach item="id" collection="idList" open="(" separator="," close=")">
#{item}
</foreach>
■死なないやつ
WHERE id IN (${ids})
※idsが上に記載した'001', '002', '003', '004'...という1つの文字列。
#{ids}じゃなくて${ids}としているとこもポイント。
#{ids}だと、文字列全体をシングルクォートで囲われてしまう。
★以下忘れずにメモ
基本は#{}でOKなはず、${}なんてほぼほぼ出番ない。
もし画面入力値を${}でバインドしたら、SQLインジェクションし放題になっちまうから、${}に渡す値は必ずシステム内で決めた値にすること。