突破ファイルおもしろいよね。

 

さてさて、タイトルの通り、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インジェクションし放題になっちまうから、${}に渡す値は必ずシステム内で決めた値にすること。