我有下表:
CREATE TABLE SOAUDIT
(SOU_USER CHAR(8 BYTE),
SOU_ORDREF CHAR(8 BYTE),
SOU_TYPE CHAR(1 BYTE),
SOU_DESC CHAR(50 BYTE))
在前三列上定义了一个唯一索引(但没有主键,这是我们无法控制的)。
在表格中有一些记录:
| SOU_USER | SOU_ORDREF | SOU_TYPE | SOU_DESC |
|----------|------------|----------|------------------|
| proust | | S | recherche |
| joyce | 12345678 | S | pelurious |
| orwell | 19841984 | T | doubleplusungood |
| camus | 34598798 | P | peiner |
仔细观察,看来SOU_ORDREF中用户'proust'的值是一个8个字符的空字符串。
现在,我需要做的是根据它们的唯一值(我将从SQL Server数据库中收到这些表来查询该表(只是为了使问题复杂化)。在SOU_ORDREF的情况下,搜索值将是是一个空白领域:
SELECT *
FROM SOAUDIT
WHERE (SOU_USER, TRIM(SOU_ORDREF), SOU_TYPE)
IN (('proust', null, 'S'))
这不会返回我正在寻找的记录。
当我按如下方式重写查询时:
SELECT *
FROM SOAUDIT
WHERE (SOU_USER, SOU_TYPE)
IN (('proust', 'S'))
AND TRIM(sou_ordref) is null
然后我做获得所需的记录。
但是,我希望能够将多个记录传递到WHERE
子句中,因此第二个版本并没有真正帮助。
答案 0 :(得分:3)
Oracle - 默认情况下 - 将空字符串和NULL
视为同一件事。
这会导致尴尬的行为,因为与NULL
的比较几乎永远不会返回true。因此,where sou_ordref = ''
之类的简单表达式永远不会返回true,因为它等同于where sou_ordref = NULL
。
以下是一种解决方法:
SELECT *
FROM SOAUDIT
WHERE (SOU_USER, COALESCE(TRIM(SOU_ORDREF), ' '), SOU_TYPE) IN
( ('proust', ' ', 'S') )
请注意,这会用空格替换空字符串(NULL
)。然后将结果与空格进行比较。
答案 1 :(得分:0)
尝试这种方式:
SELECT *
FROM test
WHERE SOU_USER = 'proust'
AND SOU_TYPE = 'S'
AND TRIM(sou_ordref) = ''
由于空char不同于NULL