Null条件を許容するSQL

PreparedStatementAndNull

312 :1/3:05/03/12 03:17:26 ID:???
突然ですが,面白い SQL を思いついたので,ご意見を頂きたいです.
興味を持たれた方は使ってみてくだちい。

一般的に,SQL の発行は,プリペアドステートメントを使う方がよいとされている.その理由は,
DBMS のキャッシュが良く効く.
SQL インジェクション等の危険が避けられる,等.

しかし,webアプリの検索フォームなどでは,プリペアドステートメントは使えない場合が多かった.検索条件項目が複数存在していて,いずれの項目も必須で無い場合,項目が入力されているかどうかをチェックし,それに合わせてSQL 文の WHERE 句の内容をツギハギしなければならないからだ.

SQL文そのものも,そしてそれにセットする引数の個数も可変なので,プリペアドステートメントを使うのは無理だったのである.

今回思いついたのは,このような条件で,プリペアドステートメントを使う方法である.


313 :2/3:05/03/12 03:19:15 ID:???
やることは大変簡単で,

1. WHERE 句の内容全てを 括弧で囲み,最後に「IS NOT FALSE」という述語を付ける.
2.空欄になっている,検索条件に含めない項目には,NULL をセットする.
 (空文字列や空白をセットしてはいけない)

この二つだけである.

例)ユーザID,職業,年齢を条件として検索する.どれも必須項目でない.
SELECT *
FROM Table_Name
WHERE
(
      user_id = ?
  AND   profession = ?
  AND   age >= ?
  AND   age < ? )IS NOT FALSE ORDER BY user_id 314 :3/3:05/03/12 03:20:43 ID:??? このように書くと,null をセットした項目は,検索条件として使われないかのように振舞う.SQL を if 文でツギハギにする必要も無くなり,ぐっとコードが読みやすくなると思う. なんでこういう動作になるのかというと,SQL が実は3値論理だからである. 詳しくはこの辺を参照. http://www.geocities.jp/mickindex/database/db_3vl.html (私自身とは無関係のページです) 気になるパフォーマンスだが,PostgreSQL で測定したところ,(  ) IS NOT FALSE がつかない場合と比べて,全く差は無かった. 実は既に,現在進行中のプロジェクトで使っている.今のところ,全く問題は無い. 以上です.質問スレにこういうことを書くのは,かなりスレ違いですみませんが,SQL 自体について一番詳しい方が来られるのはここだと思って,書かせていただきました.ご意見,ご批判などを伺いたいと思います.