web-dev-qa-db-ja.com

where句でのOracle / PL SQL / SQL null比較

処理に関する質問は、クエリでnull値になります。

たとえば、私は次のフィールドと値を持つ次のテーブルを持っています

TABLEX
Column1
1        
2        
3      
4        
5      
---------
Column2
null
A
B
C
null

特定のプロシージャでvariableYを渡しています。プロシージャ内には、このようなカーソルがあります

CURSOR c_results IS
SELECT * FROM TABLEX where column2 = variableY

今、問題は、variableYがnull、A、B、Cのいずれかである可能性があることです。variableYがnullの場合、column2がnullであるすべてのレコードを選択し、そうでなければcolumn2がA、B、またはCのいずれかです。

上記のカーソル/クエリを実行できません。variableYがnullの場合、比較が必要なため機能しません。

CURSOR c_results IS
SELECT * FROM TABLEX where column2 IS NULL

Nullまたは文字列変数に対応するカーソル/クエリを使用する必要があります。

私の質問が少し紛らわしい場合は申し訳ありません。私は物事を説明するのが苦手です。前もって感謝します。

19
user2447740

そのパラメーターの内容に応じて異なるSQLを生成するか、次のようにSQLを変更します。

WHERE (column2 = variableY) OR (variableY IS NULL AND column2 IS NULL)

OracleのAsk Tom氏は次のように述べています。

where decode( col1, col2, 1, 0 ) = 0  -- finds differences

または

where decode( col1, col2, 1, 0 ) = 1  -- finds sameness - even if both NULL

NULLカラムを等しいものとして安全に比較

6
rghome

あなたが見ているデータによっては適切でないかもしれませんが、私が見た(そして使用した)1つのトリックは、NVL(fieldname、somenonexistentvalue)を比較することです。

たとえば、AGEがオプションの列である場合は、以下を使用できます。

if nvl(table1.AGE,-1) = nvl(table2.AGE,-1)

これは、あなたがknowが許可されない値があることに依存しています。年齢は良い例です。給与、シーケンス番号、その他の負の数にはなりえない数値です。文字列はもちろんトリッキーかもしれません-「xyzzymaryhadalittlelamb」などの名前の人は誰もいないと言うかもしれませんが、その仮定で実行した日は、その名前の人を雇うことを知っています!!

「a = bまたは(aはnullで、bはnullです)」は、それを解決する従来の方法です。経験豊富なプログラマでさえその一部を時々忘れてしまうので、これは残念です。

2
JOATMON

以下は「トップ」の回答に似ていますが、より簡潔です。

WHERE ((column2 = variableY ) or COALESCE( column2, variableY) IS NULL)

2
drjumper

あなたは次のようなものを使うことができます:

SELECT * FROM TABLEX WHERE COALESCE(column2, '') = COALESCE(variableY, '')

(COALESCEは最初の非NULL値を取ります)

これは、列のコンテンツを ''(空の文字列)にできない場合にのみ機能することに注意してください。そうでない場合、NULLは ''(空の文字列)と一致するため、このステートメントは失敗します。

(編集)次のことも検討できます。

SELECT * FROM TABLEX WHERE COALESCE(column2, 'a string that never occurs') = COALESCE(variableY, 'a string that never occurs')

これにより、 ''失敗の仮説が修正されます。

2
Stef Heyenrath

DUMPを使用できます:

SELECT * 
FROM TABLEX 
WHERE DUMP(column2) = DUMP(variableY);

DBFiddle Demo

警告:これはSARG対応の式ではないため、インデックスは使用されません。

このアプローチでは、データに存在しない値(NVL/COALESCEなど)を検索する必要はありません。

0
Lukasz Szozda

ISNULL()関数を使用してみてください。変数がnullかどうかを確認でき、nullの場合はデフォルトの戻り値を設定できます。 nullからnullへのキャンパーは実際には不可能です。覚えておいてください:null <> null

0
karel
WHERE variableY is null or column2 = variableY 

for example:
create table t_abc (
id number(19) not null,
name varchar(20)
);

insert into t_abc(id, name) values (1, 'name');
insert into t_abc(id, name) values (2, null);
commit;

select * from t_abc where null is null or name = null;
--get all records

select * from t_abc where 'name' is null or name = 'name';
--get one record with name = 'name'
0
Kevin