【问题标题】:Varchar(255) as MM/DD/YYYY HH:MM to Datetime format - SQL ServerVarchar(255) 作为 MM/DD/YYYY HH:MM 到日期时间格式 - SQL Server
【发布时间】:2020-09-30 19:29:43
【问题描述】:

我知道这些日期转换问题有一百万个,但我找不到具体的问题来解决我的问题。

我有一个表,其中包含 [Date] 列,其中包含格式为 MM/DD/YYYY HH:MM 的数据,但存储为 varchar

[Date] (varchar(255),null)
12/22/2017 0:34
12/21/2017 21:33
12/21/2017 21:17
...

我需要运行查询并按日期范围过滤,所以我需要弄清楚如何转换为可用的日期时间格式。

我试过了

WHERE CONVERT(VARCHAR(255), CAST([Date] AS DATETIME), 121) between @beg1 and @end1

但得到错误

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

我尝试了其他几个答案,但没有一个与我的数据格式完全相同,因此转换不起作用。

任何帮助将不胜感激

【问题讨论】:

  • 另一个很好的例子,为什么将日期值存储在 varchar 列中是一个非常糟糕的主意
  • 然后修复设计,@mikem115,将列更改为日期和时间数据类型。 smalldatetime 在这里甚至可能是合适的。
  • 关于问题的主题,快速访问documentation 会告诉您为什么样式代码121 (yyyy-mm-dd hh:mi:ss.mmm (24h)) 不起作用;哪个会。
  • @Larnu 我感谢您的意见。不幸的是,我们通过公司收购继承了一个管理不善的数据库。我是一个只读分析师,我们的 DBA 目前有很多大鱼要炒。像这样的变通办法将在几周内成为常态,同时他们完成所有修复。我检查了文档和样式代码 22 是最接近的,但仍然无法使用 b/c of​​ the year 格式。
  • 你跳过了前几个样式:@mikem115 你想要样式 101 (mm/dd/yyyy)

标签: sql-server datetime


【解决方案1】:

正如我们许多人所提到的,真正的解决方案是修复数据类型,这意味着改变数据库。

首先,要修复数据,您需要将格式更改为 ISO 格式,特别是这里我们将使用 ISO8601 格式 (yyyy-mm-ddThh:mi:ss.mmm)。这将需要TRY_CONVERTCONVERT(第一个将数据更改为smalldatetime,第二个更改为格式化的varchar):

UPDATE dbo.YourTable
SET YourDate = CONVERT(varchar(20),TRY_CONVERT(smalldatetime, YourDate, 101), 126);

现在我们可以更改数据类型(更改为smalldatetime,因为您的数据精确到一分钟:

ALTER TABLE dbo.YourTable ALTER COLUMN YourDate smalldatetime NULL;

如果你“必须”把它留在varchar(这是一个的想法,因为你的数据有很多问题是这样的),那么你需要在WHERE 中使用TRY_CONVERT,并使用正确的样式代码:

WHERE TRY_CONVERT(smalldatetime, YourDate, 101)

然而,这是一个非常糟糕的主意,因为您的数据存在严重缺陷。例如,根据您的数据,“日期”'12/22/2017 0:34' 是今天之后'09/30/2020 21:25'),而不是之前

【讨论】:

    【解决方案2】:

    您编写的代码运行良好。您可能有格式错误的记录或不是日期格式的记录。尝试这样的代码来查找这些记录。任何具有“NULL”值的列都是 try_cast 无法成功的列。这些是炸毁您的查询的原因。

    然后您可以选择更正这些值或直接将它们从查询中排除。

    SELECT 
     [DateText], try_cast([DateText] AS Datetime) FROM Dates
    

    【讨论】:

    • 我不确定您为什么重新发布已删除的答案,但这仍然行不通,原因我在comments中解释了
    • 没有日期格式这样的东西。日期是二进制值。存储字符串而不是字节是一个主要错误
    • 是的,我们通过公司收购继承了一个管理不善的数据库。我是一个只读分析师,我们的 DBA 目前有很多大鱼要炒。像这样的变通办法将在几周内成为常态,同时完成所有修复。
    • ...看看我的comment、@mikem115、NULL 并不比正确的值好。
    • 只是好奇为什么你不只是使用 TRY_CAST,因为看起来你正在将它转换为日期时间,然后将其转换回 varchar(255)。然后进行日期范围搜索,优化器将再次将其转换回日期时间。
    猜你喜欢
    • 2015-10-08
    • 1970-01-01
    • 2017-07-20
    • 2018-11-18
    • 1970-01-01
    • 2013-10-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多