車nullの場合==nullの場合アプリケーション
質問
い検索データベースのテーブルにnullableます。時価値を私検索はNULLになります。以来、Nullに等しいものでもNULLの場合、"
where MYCOLUMN=SEARCHVALUE
失敗します。今はうれしいリゾート
where ((MYCOLUMN=SEARCHVALUE) OR (MYCOLUMN is NULL and SEARCHVALUE is NULL))
が簡単になりうる。
(私はOracle利用の場合)
解決
IsNullやNVLなどを実行できますが、それは単にエンジンの処理を増やすだけです。関数を呼び出して列の変換を行い、その後で結果を比較する必要があります。
お持ちの物を使用
where ((MYCOLUMN=SEARCHVALUE) OR (MYCOLUMN is NULL and SEARCHVALUE is NULL))
他のヒント
@アンディーズを主張することに原形をクエリするより効率的利用の汀.また試験張
SQL> DECLARE
2 CURSOR B IS
3 SELECT batch_id, equipment_id
4 FROM batch;
5 v_t1 NUMBER;
6 v_t2 NUMBER;
7 v_c1 NUMBER;
8 v_c2 NUMBER;
9 v_b INTEGER;
10 BEGIN
11 -- Form 1 of the where clause
12 v_t1 := dbms_utility.get_time;
13 v_c1 := dbms_utility.get_cpu_time;
14 FOR R IN B LOOP
15 SELECT COUNT(*)
16 INTO v_b
17 FROM batch
18 WHERE equipment_id = R.equipment_id OR (equipment_id IS NULL AND R.equipment_id IS NULL);
19 END LOOP;
20 v_t2 := dbms_utility.get_time;
21 v_c2 := dbms_utility.get_cpu_time;
22 dbms_output.put_line('For clause: WHERE equipment_id = R.equipment_id OR (equipment_id IS NULL AND R.equipment_id IS NULL)');
23 dbms_output.put_line('CPU seconds used: '||(v_c2 - v_c1)/100);
24 dbms_output.put_line('Elapsed time: '||(v_t2 - v_t1)/100);
25
26 -- Form 2 of the where clause
27 v_t1 := dbms_utility.get_time;
28 v_c1 := dbms_utility.get_cpu_time;
29 FOR R IN B LOOP
30 SELECT COUNT(*)
31 INTO v_b
32 FROM batch
33 WHERE NVL(equipment_id,'xxxx') = NVL(R.equipment_id,'xxxx');
34 END LOOP;
35 v_t2 := dbms_utility.get_time;
36 v_c2 := dbms_utility.get_cpu_time;
37 dbms_output.put_line('For clause: WHERE NVL(equipment_id,''xxxx'') = NVL(R.equipment_id,''xxxx'')');
38 dbms_output.put_line('CPU seconds used: '||(v_c2 - v_c1)/100);
39 dbms_output.put_line('Elapsed time: '||(v_t2 - v_t1)/100);
40 END;
41 /
For clause: WHERE equipment_id = R.equipment_id OR (equipment_id IS NULL AND R.equipment_id IS NULL)
CPU seconds used: 84.69
Elapsed time: 84.8
For clause: WHERE NVL(equipment_id,'xxxx') = NVL(R.equipment_id,'xxxx')
CPU seconds used: 124
Elapsed time: 124.01
PL/SQL procedure successfully completed
SQL> select count(*) from batch;
COUNT(*)
----------
20903
SQL>
そして驚きだけど正しいアンディーです。Itコストを約50%以上の汀ます。でも一のコードがな整理整頓や優雅なしにすることができます。またこの手順を複数回の結果はほぼ同じ。カレッジアンディ...
Expert Oracle Database Architecture で見たもの:
WHERE DECODE(MYCOLUMN, SEARCHVALUE, 1) = 1
よりシンプルかどうかはわかりませんが、時々使用しました
WHERE ISNULL(MyColumn, -1) = ISNULL(SearchValue, -1)
" -1"の置き換え列タイプに有効であるが、実際にはデータ内で検出されない可能性のある値を持つ。
注:OracleではなくMS SQLを使用しているため、" ISNULL"有効です。
NVLを使用して、次のようにnullを両側のダミー値に置き換えます。
WHERE NVL(MYCOLUMN,0) = NVL(SEARCHVALUE,0)
別の代替方法は、実行されたクエリの観点からおそらく最適であり、何らかのクエリ生成を行う場合にのみ有用です は、に基づいて必要な正確なクエリを生成することです検索値。
擬似コードが続きます。
if (SEARCHVALUE IS NULL) {
condition = 'MYCOLUMN IS NULL'
} else {
condition = 'MYCOLUMN=SEARCHVALUE'
}
runQuery(query,condition)
帯域外の値が可能な場合:
where coalesce(mycolumn, 'out-of-band')
= coalesce(searchvalue, 'out-of-band')
これは、Oracleでジョブを実行することもできます。
WHERE MYCOLUMN || 'X' = SEARCHVALUE || 'X'
ORを使用したIS NULLテストに勝る状況がいくつかあります。
DECODEを使用すると、NULLとNULLを照合できることにも驚きました。
WITH
TEST AS
(
SELECT NULL A FROM DUAL
)
SELECT DECODE (A, NULL, 'NULL IS EQUAL', 'NULL IS NOT EQUAL')
FROM TEST
試す
WHERE NVL(mycolumn,'NULL') = NVL(searchvalue,'NULL')
あなたが持っているものは大丈夫だと思います。次のように使用できます:
where NVL(MYCOLUMN, '') = NVL(SEARCHVALUE, '')
これは、レポートを駆動するOracleの機能でよく見られる状況です。ユーザーが結果を制限するために値を入力できるようにするか、すべてのレコードを返すために空白のままにする必要があります。これは私が使用したものであり、私たちにとってうまく機能しています。
WHERE rte_pending.ltr_rte_id = prte_id
OR ((rte_pending.ltr_rte_id IS NULL OR rte_pending.ltr_rte_id IS NOT NULL)
AND prte_id IS NULL)