Jam*_*ran 44 sql oracle null nullable
我希望在可空列上搜索数据库表.有时我搜索的值本身就是NULL.因为Null等于什么,甚至是NULL,说
where MYCOLUMN=SEARCHVALUE
Run Code Online (Sandbox Code Playgroud)
将失败.现在我不得不诉诸
where ((MYCOLUMN=SEARCHVALUE) OR (MYCOLUMN is NULL and SEARCHVALUE is NULL))
Run Code Online (Sandbox Code Playgroud)
有更简单的说法吗?
(如果重要,我正在使用Oracle)
And*_*ter 68
你可以做IsNull或NVL的东西,但它只是让引擎做更多工作.您将调用函数来进行列转换,然后必须比较结果.
用你拥有的
where ((MYCOLUMN=SEARCHVALUE) OR (MYCOLUMN is NULL and SEARCHVALUE is NULL))
Run Code Online (Sandbox Code Playgroud)
DCo*_*kie 36
@Andy Lester声称查询的原始形式比使用NVL更有效.我决定测试那个断言:
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>
Run Code Online (Sandbox Code Playgroud)
我很惊讶地发现Andy是多么正确.NVL解决方案的成本要高出近50%.因此,即使一段代码看起来不像另一段代码那么整洁或优雅,但它可能效率更高.我多次运行此程序,每次结果几乎相同.感谢安迪......
Chr*_*fer 13
我不知道它是否更简单,但我偶尔也会使用
WHERE ISNULL(MyColumn, -1) = ISNULL(SearchValue, -1)
Run Code Online (Sandbox Code Playgroud)
将"-1"替换为对列类型有效但也不太可能在数据中实际找到的值.
注意:我使用的是MS SQL,而不是Oracle,所以不确定"ISNULL"是否有效.
Pet*_*inl 13
在Expert Oracle数据库架构中,我看到:
WHERE DECODE(MYCOLUMN, SEARCHVALUE, 1) = 1
Run Code Online (Sandbox Code Playgroud)
使用NVL将null替换为两侧的虚拟值,如下所示:
WHERE NVL(MYCOLUMN,0) = NVL(SEARCHVALUE,0)
Run Code Online (Sandbox Code Playgroud)
另一种替代方案,从执行的查询角度来看可能是最佳的,只有在进行某种查询生成时才有用,它是根据搜索值生成所需的确切查询.
伪代码如下.
if (SEARCHVALUE IS NULL) {
condition = 'MYCOLUMN IS NULL'
} else {
condition = 'MYCOLUMN=SEARCHVALUE'
}
runQuery(query,condition)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
22960 次 |
| 最近记录: |