- PR -

SQLでNULLを取得

投稿者投稿内容
なな
ベテラン
会議室デビュー日: 2003/09/18
投稿数: 79
投稿日時: 2003-10-14 19:18
いつもお世話になっております。
画面で入力したデータをもとにwhere句をくみかえていく、というものです。
以下のようなSQLで実行しようとしました。

SELECT
A.受注CODE AS JYUCYUCD
FROM 受注TABLE A,
(SELECT 受注番号,
SUM(契約金) AS 契約金
FROM 契約TABLE
WHERE 受注番号 = NVL(%JYUCYUCD%,受注番号)
GROUP BY 受注番号) B
WHERE
A.受注番号 = NVL(%JYUCYUCD%,A.受注番号)

上記のようなSQLをつくり
画面上の項目で入力された場合は
%JYUCYUCD%部分に入力された文字に置換し、もし画面で入力されなかった場合はNULLを置換するという処理で行おうと思ったのですが
NVL(NULL,受注番号)だとデータがNULLのものは取得されません。
ORを使うやり方も考えたのですがレスポンスの関係上、ORはなるべく使いたくありません。
何かいいSQLの組み方をご存知であればご教授願います。
ぴで
大ベテラン
会議室デビュー日: 2002/10/10
投稿数: 123
お住まい・勤務地: 東京
投稿日時: 2003-10-15 00:17
引用:

A.受注番号 = NVL(%JYUCYUCD%,A.受注番号)

上記のようなSQLをつくり
画面上の項目で入力された場合は
%JYUCYUCD%部分に入力された文字に置換し、もし画面で入力されなかった場合はNULLを置換するという処理で行おうと思ったのですが
NVL(NULL,受注番号)だとデータがNULLのものは取得されません。

WHERE A.受注番号 = NVL(%JYUCYUCD%,A.受注番号)でNULLの場合だと
WHERE A.受注番号 = A.受注番号 ですから受注番号がNULL以外の全てのレコードがヒットしますよね。
NULLをヒットさせるには"IS NULL"しかありません。
アティ
ベテラン
会議室デビュー日: 2003/08/14
投稿数: 91
お住まい・勤務地: KANAGAWA
投稿日時: 2003-10-15 00:23
DBMSによって違うので合っているか分かりませんが、
ORACLEの場合、NULLと比較をする場合には、
A.受注番号 IS NULL
でないと、いけないと思います。
A.受注番号 = NULL
の式だと、式自体が偽になるため、何も取得できません。
あれ?というかNVLの使い方が間違っているような気がしますよ。
NVL(変数,定数)って使い方じゃないのかな?
変数がNULLだったら、定数に変換とかだと思ったんですが。
例:NVL(受注番号,'9999')
間違っていたらごめんなさい。
ぴで
大ベテラン
会議室デビュー日: 2002/10/10
投稿数: 123
お住まい・勤務地: 東京
投稿日時: 2003-10-15 00:51
引用:
あれ?というかNVLの使い方が間違っているような気がしますよ。
NVL(変数,定数)って使い方じゃないのかな?
変数がNULLだったら、定数に変換とかだと思ったんですが。
例:NVL(受注番号,'9999')
間違っていたらごめんなさい。

使えますよ。最終的に評価されて値に置き換わるだけですから。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2003-10-15 08:42
某所で教わったテク

WHERE NVL(A.受注番号, 'NULL') = NVL(%JYUCYUCD%, 'NULL')

'NULL'は、「A.受注番号」に、絶対存在しない値にしてください。←数値から値に訂正。文字列でもかまわないので。

って、あれ?「A.受注番号」がNULLのものを拾う?受注番号にNULLって、いいの?


#追加
ところで、Oracleでは日本語のオブジェクト名を正式にはサポートしていません。必ず'"'ダブルクォーテーションで囲みましょう。予期しない動作を行う場合があります。

[ メッセージ編集済み 編集者: Jitta 編集日時 2003-10-15 09:54 ]
ぴで
大ベテラン
会議室デビュー日: 2002/10/10
投稿数: 123
お住まい・勤務地: 東京
投稿日時: 2003-10-15 09:26
引用:
NULLをヒットさせるには"IS NULL"しかありません。

は言い過ぎでしたね。
NULLを変換するには、NVL、NVL2、COALESCEなどがありますから、
これらを使ってもヒットさせることはできますね。
いつインデックス対象となるか分かりませんから、あまり対象カラムに関数使わないですけど。
(ファンクションインデックスの場合を除く)
なな
ベテラン
会議室デビュー日: 2003/09/18
投稿数: 79
投稿日時: 2003-10-15 10:10
ぴでさん、アティさん、Jittaさん、返答ありがとうございました。
Jittaさんの方法で

引用-----------------------------------------------------

WHERE NVL(A.受注番号, 'NULL') = NVL(%JYUCYUCD%, 'NULL')

---------------------------------------------------------
早速試してみたのですが
たしかに%JYUCYUCD%にNULL以外のものが置換された場合はうまくいくのですが
この場合だと%JYUCYUCD%にNULLがはいるとNULLのデータ
しか持ってこれません。
%JYUCYUCD%がNULLのばあいはA.受注番号データを全件取得したいのですが・・。
言葉足らずで申し訳ありませんでした。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2003-10-15 10:18
引用:

ぴでさんの書き込み (2003-10-15 09:26) より:

いつインデックス対象となるか分かりませんから、あまり対象カラムに関数使わないですけど。


 実行計画を見たところ、「IS NULL」を指定するとFULL ACCESSでした。したがって、ORで連結するよりは高速、NULL以外で検索するよりは低速、というところでしょうか。
高速に検索したい場合はNOT NULLのカラムにインデックスをつける、ということですね。



 それから、NVL(arg1, arg2)ですが、arg1とarg2の型をあわせておかないといけないようです。arg2に文字列'NULL'を指定し、arg1に数値列を指定すると、エラー(ORA-01722: 数値が無効です。)となりました。

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