【问题标题】:How can I convert a Varchar date to an actual Date?如何将 Varchar 日期转换为实际日期?
【发布时间】:2018-04-26 14:42:29
【问题描述】:

我有一个数据类型 = varchar(50) 的字段,我有几种不同的日期格式,如下所示:

2019-06-17
01/11/19
2019-08-21
08/04/13
10/03/17
11/22/08
2018-06-07

我在表中添加了一个新字段,数据类型 = 日期。如何将 varchar(50) 字段中的所有日期转换为日期字段中的实际日期?

我以为就这么简单:

update TBL_MULTI_LD_Balance_HIST
set [actual_date] = CONVERT(VARCHAR(10), Date, 110)

update TBL_MULTI_LD_Balance_HIST
set [actual_date] = CAST([Date] as Date)

但现在我收到此错误:'Msg 241, Level 16, State 1, Line 65 从字符串转换日期和/或时间时转换失败。'

【问题讨论】:

  • 什么版本的 SQL Server?
  • ,而不是字段...
  • SQL Server 2008.
  • 如果这些值都是不同的格式,你将如何转换08/04/13? 4 月 8 日还是 8 月 4 日?
  • 除非您知道每个日期使用的确切格式,否则您不能简单地对它们应用批处理。有些会在某种格式下转换并在另一种格式下失败。首先将值标准化为众所周知的格式。

标签: sql sql-server sql-server-2008


【解决方案1】:

你可以跑

SELECT *
FROM TBL_MULTI_LD_Balance_HIST
WHERE ISDATE([date]) = 0

这将为您提供给您带来问题的列表。然后您可以手动修复这些并在之后运行您的原始更新。这不是万无一失的,但至少会给你一个很好的起点。

【讨论】:

    【解决方案2】:

    在 SQL Server 2012+ 中,它就像您建议的那样简单,因为 SQL Server 在转换日期方面非常灵活。但是有些东西是无法转换的。而不是cast() 使用try_cast()try_convert()

    update TBL_MULTI_LD_Balance_HIST
        set [actual_date] = try_cast([Date] as Date);
    

    在做这件事之前,你可以通过做得到不转换的值:

    select [date]
    from TBL_MULTI_LD_Balance_HIST
    where try_cast([Date] as date) is null;
    

    如果所有值都符合您的格式,那么您就不会遇到问题。 cast() 就可以了。事实并非如此,因此在 2012 年之前没有好的解决方案。你可以试试:

    update TBL_MULTI_LD_Balance_HIST
        set [actual_date] = (case when [date] like '[0-1][0-9]/[0-3][0-9]/[0-9][0-9]'
                                  then cast([Date] as Date)
                                  when [date] like '[12][0-9][0-9][0-9]-[0-1][0-9]-[0-3][0-9]'
                                  then cast([Date] as Date)
                             end);
    

    显然,这仍然会导致糟糕的匹配,例如 4 月 34 日,但在这种情况下,这些通常不是问题。人们输入了一些字符串,例如“none”。

    【讨论】:

    • @Lamu 。 . .我认为该标签是在我回答时添加的。
    • LaRNu。我添加了 OP 的标签,但是,他们发表了评论。 :)
    【解决方案3】:

    一种选择是使用简单的 CASE。 但是,您的日期不明确,例如 01/11/19 ...假设 MDY 这将转换为 2019-01-11

    示例

    Declare @YourTable Table ([SomeCol] varchar(50),Date date )
    Insert Into @YourTable Values 
     ('2019-06-17',null)
    ,('01/11/19',null)
    ,('2019-08-21',null)
    ,('08/04/13',null)
    ,('10/03/17',null)
    ,('11/22/08',null)
    ,('2018-06-07',null)
    ,('Not a Date',null)
    ,('2017-31-31',null)
    
    Update @YourTable 
      set [Date] = case when IsDate(SomeCol)=0 then null else convert(date,SomeCol) end
    
    Select * from @YourTable
    

    更新表格

    SomeCol     Date
    2019-06-17  2019-06-17
    01/11/19    2019-01-11
    2019-08-21  2019-08-21
    08/04/13    2013-08-04
    10/03/17    2017-10-03
    11/22/08    2008-11-22
    2018-06-07  2018-06-07
    Not a Date  NULL
    2017-31-31  NULL
    

    【讨论】:

      【解决方案4】:

      你可以尝试把所有的/,-全部替换掉​​,对所有的日期采用同样的格式,然后再转换。

      【讨论】:

      • 它原来是日期字段中的“US1000001”记录,它被扔掉了。我删除了那条记录,一切正常。我想知道为什么 SQL Server 不建议提供更具描述性的错误消息。软件基本知道错误是什么,但是错误信息很模糊。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多