【问题标题】:Convert varchar into datetime in SQL Server在 SQL Server 中将 varchar 转换为日期时间
【发布时间】:2010-12-03 08:34:51
【问题描述】:

如何在 SQL Server 2008 中将格式为 mmddyyyy 的字符串转换为 datetime

我的目标列在DateTime

我已尝试使用 Convert 和大多数 Date 样式值,但我收到一条错误消息:

'将 varchar 数据类型转换为 datetime 数据类型导致值超出范围。

【问题讨论】:

  • tsql 有没有类似 MySQL 的 str_to_date 函数? dev.mysql.com/doc/refman/5.1/en/…
  • OP 想要 mmddyyyy; select convert(datetime,'12312009') -->>>_Msg 242, Level 16, State 3, Line 1 将 char 数据类型转换为 datetime 数据类型导致 datetime 值超出范围。跨度>

标签: sql sql-server sql-server-2008 tsql type-conversion


【解决方案1】:

看看 BOL 中的 CAST / CONVERT 应该是一个开始。

如果您的目标列是datetime,则无需转换,SQL 会为您完成。

否则

CONVERT(datetime, '20090101')

应该这样做。

这是一个link,应该也有帮助:

【讨论】:

  • 但这不是 OP 的格式。 OP 坚持将 mmddyyyy 转换为日期时间。
【解决方案2】:

转换将是正常的答案,但格式不是转换器可识别的格式,mm/dd/yyyy 可以使用 convert(datetime,yourdatestring,101) 进行转换,但您没有该格式,因此它会失败。

问题在于格式不标准,您必须将其操作为转换可以从可用的标准中理解的标准。

一起破解,如果你能保证格式

declare @date char(8)
set @date = '12312009'
select convert(datetime, substring(@date,5,4) + substring(@date,1,2) + substring(@date,3,2),112)

【讨论】:

    【解决方案3】:
    DECLARE @d char(8)
    SET @d = '06082020'    /* MMDDYYYY means June 8. 2020 */
    SELECT CAST(FORMAT (CAST (@d AS INT), '##/##/####') as DATETIME)
    

    返回的结果是 @d 中作为 DateTime 的原始日期字符串。

    【讨论】:

    • 但这不是 OP 的格式。 OP 坚持将 mmddyyyy 转换为日期时间。
    • Jeff Moden 同意,已更新答案以反映问题的要求。
    • 感谢您的反馈。仅供参考,如果您还不知道的话,FORMAT 函数的执行时间通常比人们提出的一些更复杂的 CAST/CONVERT 函数要多 43 倍(或更糟)。我通常会像瘟疫一样避免它,因为它太慢了。
    【解决方案4】:

    OP 想要 mmddyy,而普通的转换将不适用:

    select convert(datetime,'12312009')
    
    Msg 242, Level 16, State 3, Line 1 
    The conversion of a char data type to a datetime data type resulted in 
    an out-of-range datetime value
    

    所以试试这个:

    DECLARE @Date char(8)
    set @Date='12312009'
    SELECT CONVERT(datetime,RIGHT(@Date,4)+LEFT(@Date,2)+SUBSTRING(@Date,3,2))
    

    输出:

    -----------------------
    2009-12-31 00:00:00.000
    
    (1 row(s) affected)
    

    【讨论】:

    • +1,但是不用拼接字符串不是很好吗? techonthenet.com/oracle/functions/to_date.php
    • @dwerner,如果你不想做这样的事情,那么不要存储在不正确的数据类型中。
    • 如果我错了,请纠正我,但这是问题提出的问题。我的建议是使用针对目的量身定制的功能。
    • 您的“建议”对我来说似乎是普通的公司先令。使用完全不同的数据库技术的建议是否对几乎每个数据库开发人员有用或实用,即使是首席架构师?并不真地。似乎将信息简单地存储为不作为 varchar 字符串或至少作为 ISO 格式的字符串可能更容易。
    • @LucasLeblanc,您必须考虑 OP 的要求。 OP 没有详细说明为什么需要这样做,可能他们正在与他们无法改变的事物交互。另外,我永远不会建议您将日期存储为字符串,这就是您最终遇到此类问题的方式。
    【解决方案5】:

    您可能有无法转换的不良数据。日期永远不应该存储在 varchar 中,因为它允许诸如 ASAP 或 02/30/2009 之类的日期。对数据使用 isdate() 函数查找无法转换的记录。

    好的,我用已知的良好数据进行了测试,但仍然收到了消息。您需要转换为不同的格式,因为它不知道 12302009 是 mmddyyyy 还是 ddmmyyyy。 yyyymmdd 的格式没有歧义,SQL Server 会正确转换

    我得到了这个工作:

    cast( right(@date,4) + left(@date,4) as datetime)
    

    如果您有任何非标准格式(如“112009”或某些文本值或真正超出范围的日期),您仍然会收到错误消息。

    【讨论】:

    • 在对一百万个像 OP 一样的 mmddyyyy 格式的随机日期字符串进行了一些测试之后,结果证明这是运行速度最快且编码最简单的方法。还有其他方法可以将其与性能联系起来,但是,在所有实际按照 OP 在此线程上询问的代码中,这个每次都会获胜。在一百万行上的时间不超过 25 毫秒,但考虑到编码的便利性和我测试的其他方法的负载,这个获胜。
    【解决方案6】:

    SQL Server 可以将 'YYYYMMDD' 形式的字符串隐式转换为日期时间 - 所有其他字符串都必须显式转换。这里有两个快速代码块,它们将从您正在谈论的表单中进行转换:

    版本 1 使用单位变量:

    BEGIN 
    DECLARE @input VARCHAR(8), @mon CHAR(2), 
    @day char(2), @year char(4), @output DATETIME
    
    SET @input = '10022009'   --today's date
    
    
    SELECT @mon = LEFT(@input, 2), @day = SUBSTRING(@input, 3,2), @year = RIGHT(@input,4)
    
    SELECT @output = @year+@mon+@day 
    SELECT @output 
    END
    

    版本 2 不使用单位变量:

    BEGIN 
    DECLARE @input CHAR(8), @output DATETIME
    SET @input = '10022009' --today's date 
    
    SELECT @output = RIGHT(@input,4) + SUBSTRING(@input, 3,2) + LEFT(@input, 2)
    
    SELECT @output
    END
    

    这两种情况都依赖于 sql server 进行隐式转换的能力。

    【讨论】:

      【解决方案7】:

      我很幸运遇到了类似的事情:

      Convert(DATETIME, CONVERT(VARCHAR(2), @Month) + '/' + CONVERT(VARCHAR(2), @Day)
      + '/' + CONVERT(VARCHAR(4), @Year))
      

      【讨论】:

      • OP 没有可用的变量。只是一个 MMDDYYYY 格式的字符串。
      【解决方案8】:

      此问题的根本原因可能在于区域设置 - DB 等待 YYYY-MM-DD 而应用程序发送例如 DD-MM-YYYY(俄罗斯语言环境格式),就像我的情况一样。我所做的一切 - 将语言环境格式从俄语更改为英语(美国),然后瞧。

      【讨论】:

        【解决方案9】:

        这似乎是最简单的方法..

        SELECT REPLACE(CONVERT(CHAR(10), GETDATE(), 110),'-','')
        

        【讨论】:

        • 不适用于 OP。 OP 的格式为 MMDDYYYY。
        【解决方案10】:

        插入或更新时的 SQL 标准日期必须介于 1/1/1753 12:00:00 AM 和 12/31/9999 11:59:59 PM 之间。

        因此,如果您在 1753 年 1 月 1 日以下插入/更新,您将收到此错误。

        【讨论】:

        • OP 卡在 MMDDYYYY 格式上。您的信息实际上对操作没有帮助。
        【解决方案11】:

        我会使用STUFF 插入分隔字符,然后使用具有适当样式的CONVERT。像这样的:

        DECLARE @dt VARCHAR(100)='111290';
        SELECT CONVERT(DATETIME,STUFF(STUFF(@dt,3,0,'/'),6,0,'/'),3)
        

        首先您使用两次STUFF 得到 11/12/90 而不是 111290,然后使用 3 将其转换为 datetime(或任何其他合适的格式:使用 @ 987654328@ 用于德语,- 用于英国...)More details on CAST and CONVERT

        最好是正确存储日期和时间值。

        • 这应该是“通用非分隔格式”yyyyMMdd
        • 或者(尤其是在 XML 中)它应该是 ISO8601:yyyy-MM-ddyyyy-MM-ddThh:mm:ss More details on ISO8601

        任何特定于文化的格式迟早都会导致麻烦......

        【讨论】:

        • 当你有像 201901 或 201905 这样的字符串格式时,这非常有用
        【解决方案12】:

        使用 Try_Convert:如果转换成功,则返回一个转换为指定数据类型的值;否则,返回 null。

        DECLARE @DateString VARCHAR(10) ='20160805'
        SELECT TRY_CONVERT(DATETIME,@DateString)
        
        SET @DateString ='Invalid Date'
        SELECT TRY_CONVERT(DATETIME,@DateString)
        

        链接:MSDN TRY_CONVERT (Transact-SQL)

        【讨论】:

        • 但这不是 OP 的格式。 OP 坚持将 mmddyyyy 转换为日期时间。
        【解决方案13】:

        我发现这对我的转换很有帮助,无需字符串操作。 https://docs.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql

        CONVERT(VARCHAR(23), @lastUploadEndDate, 121)
        

        yyyy-mm-dd hh:mi:ss.mmm(24h) 是我需要的格式。

        【讨论】:

        • 但这不是 OP 的格式。 OP 坚持将 mmddyyyy 转换为日期时间。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-02
        • 2020-12-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多