【问题标题】:Compatible SQL to test for not null and not empty strings用于测试非空字符串和非空字符串的兼容 SQL
【发布时间】: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; 的正确部分。是的,现在一切都清楚了,谢谢!我的意思是,虽然你只是这么认为,但这与实际发生的情况非常相似。

标签: sql sql-server oracle


【解决方案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 的计算结果相同。

    【讨论】:

      猜你喜欢
      • 2017-06-12
      • 1970-01-01
      • 2018-07-04
      • 2012-01-24
      • 2012-04-03
      • 1970-01-01
      • 2021-12-03
      • 2016-05-26
      • 2013-04-29
      相关资源
      最近更新 更多