【问题标题】:Text Date Convert issues文本日期转换问题
【发布时间】:2019-11-24 19:40:06
【问题描述】:

我有一个带有纯文本“日期时间”的数据源,但在转换它时遇到问题。 当我尝试将其转换为各种日期格式并将其插入新表时,出现错误。

数据示例:

"18-07-2015 11:50:30am"

源表结构:

CREATE TABLE [dbo].[Conv_COMMUNICATIONEXPORT]([datetime] [varchar](255) NULL) 

目标表结构:

CREATE TABLE [dbo].[TB_X_Attachment]([CreatedDate] [datetime] NULL)

插入数据出错:

Msg 242, Level 16, State 3, Line 4
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.

当我运行以下选择时,最后一个转换返回错误:

SELECT CONVERT(VARCHAR(30), GETDATE(), 120) ,getdate()  ,CONVERT(DATE, CONVERT(VARCHAR(40), '01-01-2000'), 120)

当我在表中运行以下内容时,成功:

INSERT INTO TB_X_Attachment (CreatedDate)
CONVERT(DATE, CONVERT(VARCHAR(30), '2000-01-01'), 120) AS WORKS 

在尝试插入时,以下转换尝试均无效:

SELECT      ce.[datetime] AS VARCHAR_DATETIME,
CONVERT(VARCHAR(10), CE.[datetime], 120),
CONVERT(char(10), CONVERT(VARCHAR(10), CE.[datetime], 120),120),
CONVERT(VARCHAR(10),CONVERT(char(10), CONVERT(VARCHAR(10), CE.[datetime], 120),120),120),
CONVERT(VARCHAR,(CONVERT(VARCHAR(10), CE.[datetime], 120))) ,   
CONVERT(VARCHAR(10), CE.[datetime], 120)
FROM        Conv_ATTACHMENTEXPORT ae
INNER JOIN  Conv_COMMUNICATIONEXPORT ce
            ON ae.[attachment record id] = ce.[communication id] 

见下图,上面的转换尝试的结果

我认为如果我可以将输出反转为 YYYY-MM-DD,它可能会起作用。所有转换尝试都不想将格式设置为此。如何将输出反转为 YYYY-MM-DD?

【问题讨论】:

  • 欢迎来到世界的另一半!如果您希望能够处理 DMY 日期,那么您可能需要先使用SET DATEFORMAT DMY。这可能是最简单的选择,但当您也有时间组件时,您可能还需要一些额外的字符串操作才能使其正常工作。
  • 使用style 103 执行convert(datetime, '18-07-2015 11:50:30am', 103)
  • ...或 105 - convert(datetime, '18-07-2015 11:50:30am', 105)

标签: sql-server tsql datetime casting


【解决方案1】:

在将字符串转换为 dateTime 值时,SQL Server 非常聪明。
然而,尽管它很聪明,但日期和时间值的字符串表示非常棘手 - 这就是为什么我们有ISO 8601 标准,它保证在转换为日期时间时 SQL Server 始终正确解释。

但是,我知道您对源数据没有任何控制权,因此必须处理指定的格式。

快速查看Convert 函数文档中的Date and Time Styles 表将为您提供以下格式:

Without             With                Standard            Input/Output (3)
century (yy) (1)    century (yyyy)  

3                   103                 British/French      3 = dd/mm/yy
                                                            103 = dd/mm/yyyy

4                   104                 German              4 = dd.mm.yy
                                                            104 = dd.mm.yyyy

5                   105                 Italian             5 = dd-mm-yy
                                                            105 = dd-mm-yyyy

带有世纪的三个选项中的任何一个都会为您提供指定字符串的正确值DateTime

DECLARE @DateString varchar(30) = '18-07-2015 1:5:3pm';

SELECT  @DateString As string, 
        CONVERT(DateTime2, @DateString, 103) As [103], 
        CONVERT(DateTime2, @DateString, 104) As [104], 
        CONVERT(DateTime2, @DateString, 104) As [105]

结果:

string                  103                     104                     105

18-07-2015 1:5:3pm      2015-07-18 13:05:03     2015-07-18 13:05:03     2015-07-18 13:05:03

由于原始字符串使用连字符作为分隔符,我会使用意大利标准 (105),因为它最接近源字符串格式。

【讨论】:

    【解决方案2】:

    试试这个:

    select convert(datetime, [datetime], 105) 
    

    [datetime] 是您的 varchar 列,其中包含要转换的日期

    或者干脆

    select convert(datetime, '18-07-2015 11:50:30pm', 105) 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多