簡體   English   中英

關於where子句的Oracle / PL SQL / SQL null比較

[英]Oracle/PL SQL/SQL null comparison on where clause

只是關於交易的問題將在查詢中使用空值。

例如,我有下表,其中包含以下字段和值

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

我在特定程序上傳遞變量Y. 程序里面是這樣的游標

CURSOR c_results IS
SELECT * FROM TABLEX where column2 = variableY

現在問題是變量Y可以是null,A,B或C如果變量Y是null我想選擇column2為null的所有記錄,否則其中column2是A,B或C.

我不能做上面的游標/查詢,因為如果variableY為null,它將無法工作,因為比較應該是

CURSOR c_results IS
SELECT * FROM TABLEX where column2 IS NULL

我應該使用哪種光標/查詢來容納null或string變量。

對不起,如果我的問題有點令人困惑。 我解釋事情並不是那么好。 提前致謝。

根據該參數的內容生成不同的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列比較為等於

你可以使用類似的東西:

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')

這將解決''失敗假設。

根據您正在查看的數據可能不合適,但我見過(並使用過)的一個技巧是比較NVL(fieldname,somenonexistentvalue)。

例如,如果AGE是可選列,您可以使用:

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

這取決於您知道永遠不會允許的值。 年齡是一個很好的例子,薪水,序列號和其他數字,不能是負面的。 字符串當然可能比較棘手 - 你可能會說你永遠不會有任何人命名為'xyzzymaryhadalittlelamb'或類似的東西,但是當你運行這個假設時,你知道他們會聘請一個有這個名字的人!

所有這一切說:“其中a = b或(a為空,b為空)”是傳統的解決方法。 這是不幸的,因為即使是有經驗的程序員有時也會忘記它的一部分。

下面類似於“頂部”答案,但更簡潔:

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

嘗試使用ISNULL()函數。 您可以檢查變量是否為null,如果是,則設置默認返回值。 將null歸零可能無法實現。 記住:null <> null

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'

您可以使用DUMP

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

DBFiddle演示

警告:這不是SARG表達式,因此不會使用索引。

使用此方法,您無需搜索數據中不存在的值(如NVL/COALESCE )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM