2012-07-23 141 views
2

我正在尝试创建一个Oracle查询,该查询将使用基于CommandName按钮的参数。具有空值的Oracle SQL Case语句

因此,这里是我的查询

SELECT id 
FROM table 
WHERE dateTime IS (CASE WHEN :CommandName = 'FIRST' THEN NULL ELSE NOT NULL END) 

所以我传递的参数,但它不工作 - 我只是得到一个Missing NULL keyword错误

我基本上不想有写两个根据输入的参数进行单独查询

甚至不确定这是否可行或者这是否正确?

任何想法?

回答

4

您可能想要更多地阅读CASE语句。

我相信你想下面的代码:尽管基于这样的假设

SELECT 
    id 
FROM 
    table 
WHERE 
    (
     (dateTime IS NULL AND :CommandName = 'FIRST') 
     OR 
     (dateTime IS NOT NULL AND NVL(:CommandName, '') <> 'FIRST') 
    ) 
+0

感谢您的信息 - 使用'!='或'<>'不同的地方说不同的东西 – 2012-07-23 17:19:11

+0

<>是ANSI标准,而!=在所有数据库系统中都不兼容(尽管在这种情况下,它在绝大多数)。 – 2012-07-23 17:37:44

+0

如果:commandName IS NULL? – jva 2012-07-23 19:11:51

0

我认为

SELECT id 
FROM table 
WHERE (dateTime IS NULL AND :CommandName='FIRST') OR (dateTime IS NOT NULL AND :CommandName <> 'FIRST') 

应该做你所需要的。

1

不使用动态SQL返回字符串 'NULL' 或 'NOT NULL',你就可以使用两个NVL()功能:

select id 
from table 
where NVL(dateTime,'FIRST') = NVL(:param,dateTime); 

但是,如果DATETIME索引(和Oracle可以索引空值),部份NVL ()函数将禁用索引。

+0

阿有趣的方式:param为FIRST或NULL – 2012-07-23 17:14:23

+0

甲骨文将评估“NULL = NULL”为NULL,所以它不会返回任何东西在这种情况下。 – jva 2012-07-23 19:05:23

+1

@jva真,但当dateTime为空('FIRST')时,运算符左侧的第一个NVL()提供了一个替代值,因此第一个表达式不会为空。 IF:param为null,则dateTime列将用于所有行,并且由于FIRST'= NULL'的计算结果为false,因此将放弃其中datetime实际上为null的任何行。也就是说,我正在用'OR'运算符挖掘@John D的解决方案,尽管我会在括号中包含这对互斥的条件,所以其他谓词将按预期应用。 – Wolf 2012-07-23 19:19:23