Where Char子句中的空字符?

时间:2016-10-04 10:27:24

标签: sql oracle oracle11g

我有下表:

  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子句中,因此第二个版本并没有真正帮助。

2 个答案:

答案 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