【问题标题】:Handling a value of zero in a date datatype处理日期数据类型中的零值
【发布时间】:2021-08-20 21:28:51
【问题描述】:

我报告的数据库使用 decimal(17,6) 作为日期字段的数据类型。例如,此字段中的当前日期/时间为20210820.171900。不寻常,但无论如何。我需要将原始日期字段从十进制(17,6)转换为日期时间。这就是我所拥有的:

SELECT convert(datetime, convert(varchar,convert(int, lastmoddatetime)), 0)
from Table1

只要此列中没有记录的值为零,上述语句就可以正常工作。不幸的是,如果没有为其计算日期,则该列值默认为零 (0.000000)。每当一列的值为零时,我都会收到以下错误:

从字符串转换日期时转换失败。

我该如何克服这个问题?最终,我需要将 dateadd 函数应用于 lastmoddatetime 字段。

注意:在您建议更改列定义之前,此数据库起源于 1990 年代,我不允许对数据库结构进行任何更改。

【问题讨论】:

  • 先发制人的注意事项: 保存您的 cmets 关于该字段的设置有多愚蠢以及需要正确创建它。我同意他们的看法。然而,这个笨重的数据库起源于 1990 年代,我不能对数据库结构进行任何更改。
  • 期望的结果是那些日期值为零的记录,它将被转换为实际日期(或保持为零,不太可能),然后可以从结果集中过滤掉。
  • 请向minimal reproducible example 提供示例数据、您的尝试和您想要的结果。
  • 我们不知道“日期字段(十进制数据类型)”是什么意思。我们看不到您的数据来推断它使用的任何方案
  • 我已经编辑了原始问题,所以希望我更清楚。我的问题的底线是在转换为日期数据类型时如何处理零值。

标签: sql sql-server tsql datetime


【解决方案1】:

您可以使用NULLIF 来清除这些值

convert(datetime, convert(varchar(15), convert(int, NULLIF(lastmoddatetime, 0.0))), 0)

【讨论】:

  • 好老KISS!!
【解决方案2】:

使用TRY_CONVERTCASE - 取决于您希望如何处理零大小写。

SELECT
    -- If desiring null for 0 and SQL Server 2012+
    TRY_CONVERT(date, CONVERT(varchar, CONVERT(int, lastmoddatetime)), 0)
    , CASE WHEN lastmoddatetime <> 0
    -- If desiring some other valid date or < SQL Server 2012
    THEN CONVERT(date, CONVERT(varchar, CONVERT(int, lastmoddatetime)), 0)
    ELSE NULL /* Whatever valid datetime value you want */ END
FROM (
  VALUES (20210820.171900), (0.0)
) x (lastmoddatetime);

我注意到这忽略了时间部分 - 所以我转换为date 而不是上面的datetime。如果您需要处理时间组件,则需要更新您的问题。

【讨论】:

    【解决方案3】:

    另一种选择。

    您可以使用left()try_convert() 将其缩小一点

    示例

    Declare @YourTable table (lastmoddatetime numeric(17,6))
    Insert into @YourTable values
     (20210820.171900)
    ,(0.0)
    
    
    Select AsDate     = try_convert(date,left(lastmoddatetime,8))
          ,AsDateTime = try_convert(datetime,left(lastmoddatetime,8))
     From  @YourTable
    

    结果

    AsDate        AsDateTime
    2021-08-20    2021-08-20 00:00:00.000
    NULL          NULL
    

    【讨论】:

      【解决方案4】:

      使用

      convert(datetime,convert(int,lastmoddatetime),0)

      【讨论】:

      • 是的,这是将其转换为 DATETIME 的正确方法。但是,当有一些记录在这个字段中有 0.000000 时,它会出错。我将如何处理?
      • 不,我测试过它适用于高达 0.000000 的记录,无需转换 varchar
      • 是的,当日期字段为零时,它允许我克服错误,但当日期字段值为 20210823 时,它现在由于日期范围错误而出错。在您的公式中,值 1 = 1 天。未来 2000 万天超出范围。但是,您让我在这里偶然发现了实际答案,所以您的答案最有帮助。谢谢。
      猜你喜欢
      • 1970-01-01
      • 2018-12-12
      • 2016-12-13
      • 2013-01-21
      • 2023-04-09
      • 1970-01-01
      • 2018-02-08
      • 2021-10-12
      • 2022-01-07
      相关资源
      最近更新 更多