使用dateadd

时间:2015-07-07 11:53:22

标签: sql sql-server

我在使用CASE的SQL语句中表达了一些奇怪的行为。它可以通过以下示例重现:

SELECT
    CASE
    WHEN 1=1
        THEN 'foo'
    WHEN 1=2
        THEN (DATEADD(s, 1435586700, '01/01/1970 00:00:00'))
    WHEN 1=3
        THEN (DATEADD(s, 1435586700, '01/01/1970 00:00:00'))
    ELSE
        'bar'
    END AS result

如果在SQL Server 2008上执行此操作,则不返回任何结果。只要您为第二个或第三个案例更改它成功,它就会返回一个值。如果您完全删除这些案例,它就可以正常工作。

起初我认为在任何情况下执行DATEADD都会出现问题,并且因为传递参数值而失败。但在我的例子中,它们是不变的,无论如何都应该有用。

这里发生了什么?

3 个答案:

答案 0 :(得分:6)

case是一个表达式,其类型在编译时确定。但是,直到运行时才会实际评估这些值。

根据类型转换规则,我认为表达式将返回datetime。当符合'foo'条件时,这会导致'bar'when值出错。

答案 1 :(得分:1)

各种选项中有不同的类型。这是完全错误的 - 案例表达式必须只有一种类型。

实际上,这可能会尝试将结果转换为datetime。它无法将'foo'转换为datetime

至于您关于dateadd失败的说明,这不会是一个问题 - 实际上,case避免评估的几种方法之一所有选择。

案例表达方式有点脆弱;但是这应该已经发出警报 - 为什么你会考虑在同一列中返回两种不同的数据类型吗?这肯定会给你迟早带来麻烦(在这种情况下,更快;但它可能会在将来给你带来更多麻烦)。将两种不同的可能性分成两列(例如错误代码+日期时间等),或者将格式保留在应用程序上而不是将其填充到数据库中。

答案 2 :(得分:1)

试试这个...... 案例表达式应该是单一类型,所以我改变了单一类型的案例选项。

SELECT
    CASE
    WHEN 1=1
        THEN 'foo'
    WHEN 1=2
        THEN CONVERT(VARCHAR(20),((dateadd(s, 1435586700, '01/01/1970 00:00:00'))))
     WHEN 1=3
        THEN CONVERT(VARCHAR(20),(dateadd(s, 1435586700, '01/01/1970 00:00:00'))
    ELSE
        'bar'
    END AS result
相关问题