用于测试非空字符串和非空字符串的兼容 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 &lt;&gt; '' 不起作用。如果column 具有(非空)值,则条件 返回true,这就是您想要的。我错过了什么?此外,如果column 为空,这意味着Oracle 为“为空”,则条件将返回“假”或“未知”,在这种情况下,后者与前者相同。那么,再说一遍,为什么不能在 Oracle 中使用呢? @Andriy:我认为问题在于,在 Oracle 中,column &lt;&gt; '' 将被评估为 column &lt;&gt; NULL,因此 'some text' &lt;&gt; '' 将被评估为 'some text' &lt;&gt; NULL = NULL(或 Unknown正如你所说的那样)。我想有人会希望它产生 True 而不是 Unknown。 @ypercube:我现在明白了。一直以来,我都在想column 并错过了'' 作为&lt;&gt; 的正确部分。是的,现在一切都清楚了,谢谢!我的意思是,虽然你只是这么认为,但这与实际发生的情况非常相似。 【参考方案1】:

NULLIF 在 Oracle (doc) 和 SQL Server (doc) 上均可用。这个表达式应该有效:

NULLIF(column, '') IS NOT NULL

在两个服务器中,如果columnNULL,那么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的主要内容,如果未能解决你的问题,请参考以下文章

MySQL中如何排除null和空字符串的条件

408数据结构与算法—串和BF算法(二十四)

408数据结构与算法—串和BF算法(二十四)

串和数组

数据结构与算法(C#)入门 --- 串和数组

Oracle 11 PL/SQL:检查变量是不是为空、空字符串和无结果