用于测试非空字符串和非空字符串的兼容 SQL
Posted
技术标签:
【中文标题】用于测试非空字符串和非空字符串的兼容 SQL【英文标题】:Compatible SQL to test for not null and not empty strings 【发布时间】:2011-09-21 09:52:09 【问题描述】:我想为 Oracle 数据库和 Microsoft SQL 服务器提供兼容的 SQL。
我想要一个兼容的 SQL 表达式,它将为非空字符串和非空字符串返回 true。
如果我使用:
column <> ''
它可以在 Microsoft SQL 服务器上工作,但不能在 Oracle 数据库上工作(因为 Oracle 的 '' 为空)
如果我使用:
len(column) > 0
它可以在 Microsoft SQL 服务器上工作,但不能在 Oracle 数据库上工作(因为它使用 length() )
【问题讨论】:
所以,即使''
在 Oracle 中是 null
,我仍然不明白为什么 column <> ''
不起作用。如果column
具有(非空)值,则条件将 返回true
,这就是您想要的。我错过了什么?此外,如果column
为空,这意味着Oracle 为“为空”,则条件将返回“假”或“未知”,在这种情况下,后者与前者相同。那么,再说一遍,为什么不能在 Oracle 中使用呢?
@Andriy:我认为问题在于,在 Oracle 中,column <> ''
将被评估为 column <> NULL
,因此 'some text' <> ''
将被评估为 'some text' <> NULL
= NULL
(或 Unknown
正如你所说的那样)。我想有人会希望它产生 True 而不是 Unknown。
@ypercube:我现在明白了。一直以来,我都在想column
并错过了''
作为<>
的正确部分。是的,现在一切都清楚了,谢谢!我的意思是,虽然你只是这么认为,但这与实际发生的情况非常相似。
【参考方案1】:
NULLIF
在 Oracle (doc) 和 SQL Server (doc) 上均可用。这个表达式应该有效:
NULLIF(column, '') IS NOT NULL
在两个服务器中,如果column
是NULL
,那么NULLIF
的输出将只传递NULL
值。在 SQL Server 上,'' = ''
,所以NULLIF
的输出将是NULL
。在 Oracle 上,''
已经是 NULL
,所以它被传递了。
这是我在 SQL Server 2008 R2 Express 上的测试:
WITH SampleData AS
(SELECT 1 AS col1, NULL AS col2
UNION ALL
SELECT 2, ''
UNION ALL
SELECT 3, 'hello')
SELECT *
FROM SampleData
WHERE NULLIF(col2, '') IS NOT NULL;
这是我在 Oracle 10g XE 上的测试用例:
WITH SampleData AS
(SELECT 1 AS col1, NULL AS col2 FROM DUAL
UNION ALL
SELECT 2, '' FROM DUAL
UNION ALL
SELECT 3, 'hello' FROM DUAL)
SELECT *
FROM SampleData
WHERE NULLIF(col2, '') IS NOT NULL;
两者都按预期返回3
。
【讨论】:
【参考方案2】:尝试缩短@DCookie 的答案。我喜欢他的( '' = '' )
测试。
CASE WHEN ( '' = '' ) THEN ( column <> '' )
ELSE ( column = column )
END
很遗憾,上述方法行不通。下一个在 SQL-Server 中工作。我现在无法在 Oracle 中测试:
CASE WHEN '' = '' THEN CASE WHEN column <> '' THEN 1 ELSE NULL END
ELSE CASE WHEN column = column THEN 1 ELSE NULL END
END
也可以写成:
( '' = '' AND column <> '' )
OR ( '' IS NULL AND column = column )
【讨论】:
SQL Server 是否允许您直接与 null 进行比较?我无法测试它,只是问。如果不是,当列为 NULL 时,您的第一个测试将失败。当列为 NULL 时,Oracle 上的第二个测试肯定会失败,因为 NULL = NULL 为 false。 @DCookie:好吧,当列为 NULL 时,我们希望它失败,不是吗?【参考方案3】:怎么样
CASE WHEN column = '' THEN NULL ELSE column END IS NOT NULL
【讨论】:
它有效,但我更喜欢 NULLIF(column, '') IS NOT NULL 解决方案,因为该列只有一次并且更短。 基本上,NULLIF 版本已扩展。 (+1)【参考方案4】:我认为这里的关键是区分空字符串等于 NULL 和不等于 NULL 的情况:
WHERE CASE WHEN '' = '' THEN -- e.g., SQL Server this is true
CASE WHEN col <> '' AND col IS NOT NULL THEN 'Y'
ELSE 'N'
END
WHEN COALESCE(col,NULL) IS NOT NULL THEN 'Y' -- Not SS, e.g., Oracle
ELSE 'N'
END = 'Y';
如果第一种情况为真,则空字符串与空字符串不同,我们必须测试字符串是否不为空和字符串是否为空字符串。否则,我们的任务会更容易,因为空字符串和 null 的计算结果相同。
【讨论】:
以上是关于用于测试非空字符串和非空字符串的兼容 SQL的主要内容,如果未能解决你的问题,请参考以下文章