- PR -

JDBC(バインド変数)について

投稿者投稿内容
java初心者
ベテラン
会議室デビュー日: 2007/07/23
投稿数: 54
投稿日時: 2007-07-24 13:15
ご質問させて下さい。

今、JDBCを使用した開発を行っているのですが、
StringでSQLを作成する際、WHERE句で

-----------------------------------------------
"WHERE "+
"CODE = ? ";
-----------------------------------------------
とした場合、バインド変数として入れる変数がNULLのだったら、
自分では、そのWHEREはスルーされると
思っているのですが、スルーされないので悩んでしまっております。
比較演算記号がおかしいのでしょうか?

宜しくお願い致します。
小僧
ぬし
会議室デビュー日: 2002/08/14
投稿数: 526
投稿日時: 2007-07-24 14:16
スルーというのが、WHERE句自体が消えた状態でSQLが発行される
ということでしたら、それはありません。
バインド値がnullの場合は、WHERE句ごと含めないようにするか、
どちらでも対応できるるSQLを用意する必要があります。
あしゅ
ぬし
会議室デビュー日: 2005/08/05
投稿数: 613
投稿日時: 2007-07-24 14:20
FAQな回答をしておきます。

NULLを含む演算子の評価結果は一般的にNULLになるため、
WHEREの式が最終的に真とならない限り除外されます。

なので、SQL組み立ての時点で条件から除外するか、
-----------------------------------------------
WHERE (? IS NULL OR CODE = ?)
-----------------------------------------------
として二つの?に同じ値をバインドすればよいです。

#OracleはNULLと''が等価な特殊仕様ですが、これは例外。
nagise
ぬし
会議室デビュー日: 2006/05/19
投稿数: 1141
投稿日時: 2007-07-24 14:21
小僧氏の返答で概ね言い尽くされていますね。

Java側でnull値をバインドした場合、DB側のNULL値扱いなのですが
そもそもSQLの仕様でNULLとNULLを=で比較するとfalseになるので注意が必要です。
SQLではNULL値か比較する際にIS NULL演算になりますので。

なので、件のSQL文ではCODE = NULLの条件となり、
これは常に成り立たないので1件も対象とならないことになります。

このへんもDBの製品によって挙動が異なるんだったっけ?
小僧
ぬし
会議室デビュー日: 2002/08/14
投稿数: 526
投稿日時: 2007-07-24 14:48
引用:

このへんもDBの製品によって挙動が異なるんだったっけ?



確かJDBCドライバのバインド変数の仕様で決まっていたような気がします。
ただのSQLでNULLをイコールで比較できるDBはあったと思うんですけどね。
カーニー
ぬし
会議室デビュー日: 2003/09/04
投稿数: 358
お住まい・勤務地: 東京
投稿日時: 2007-07-24 15:33
ちょこっと補足。

引用:

Java側でnull値をバインドした場合、DB側のNULL値扱いなのですが
そもそもSQLの仕様でNULLとNULLを=で比較するとfalseになるので注意が必要です。


正確にはfalseではなく、unknownになります。
「trueにならない」という意味では、実際には問題にならない誤解なんですが。

引用:

小僧さんの書き込み (2007-07-24 14:48) より:
引用:

このへんもDBの製品によって挙動が異なるんだったっけ?



確かJDBCドライバのバインド変数の仕様で決まっていたような気がします。
ただのSQLでNULLをイコールで比較できるDBはあったと思うんですけどね。



例えばPostgreSQLは"transform_null_equals"パラメータで挙動を変更できます。
あと、多分JDBC仕様ではカバーしていないエリアです。
カーニー
ぬし
会議室デビュー日: 2003/09/04
投稿数: 358
お住まい・勤務地: 東京
投稿日時: 2007-07-24 15:36
引用:

小僧さんの書き込み (2007-07-24 14:16) より:
どちらでも対応できるるSQLを用意する必要があります。



これの例を挙げておきます。

WHERE (CODE = ? OR ? IS NULL)

2回、同じ値をバインドして下さい。

追記:あしゅさんのコメント見落としてました・・・思いっきりかぶり。

[ メッセージ編集済み 編集者: カーニー 編集日時 2007-07-24 15:37 ]
nagise
ぬし
会議室デビュー日: 2006/05/19
投稿数: 1141
投稿日時: 2007-07-24 15:42
引用:

カーニーさんの書き込み (2007-07-24 15:33) より:
引用:

Java側でnull値をバインドした場合、DB側のNULL値扱いなのですが
そもそもSQLの仕様でNULLとNULLを=で比較するとfalseになるので注意が必要です。


正確にはfalseではなく、unknownになります。
「trueにならない」という意味では、実際には問題にならない誤解なんですが。

(中略)
例えばPostgreSQLは"transform_null_equals"パラメータで挙動を変更できます。
あと、多分JDBC仕様ではカバーしていないエリアです。


なるほど。勉強になりました。
補足ありがとうございます。

スキルアップ/キャリアアップ(JOB@IT)