【问题标题】:Unable to convert varchar to datetime无法将 varchar 转换为日期时间
【发布时间】:2014-04-03 03:42:23
【问题描述】:

不幸的是,我遇到了一个将日期存储为 varchar 而不是 datetime 的数据库。 它存储多种日期格式(例如 xx/yy/zzzz、xx/yy/zz、x/y/zzzz 等)。最终,我希望尽我所能将它们全部转换为 xx/yy/zzzz。

我正在尝试进行一些数据清理并尝试一些 SELECT 语句以查看可以转换为什么。

SET DATEFORMAT DMY
SELECT MyDate, CAST(MyDate AS DATETIME) AS MyDate_Mod FROM MyTable
WHERE ISDATE(MyDate) <> 0 AND MyDate NOT LIKE '__/__/____'

这似乎执行正常。

下一个目标是查找年份大于 2000 的日期,因为某些 2 位数年份的 CAST(例如 xx/yy/zz)会自动转换为 20zz 而不是 19zz。 无论如何,所以我将 SELECT 更新为:

SELECT MyDate, CAST(MyDate AS DATETIME) AS MyDate_Mod FROM MyTable
WHERE ISDATE(MyDate) <> 0 AND MyDate NOT LIKE '__/__/____' AND YEAR(CAST(MyDate AS DATETIME)) >= 2000

运行上述语句失败,出现转换问题。

也许我认为执行顺序很重要,因为 WHERE 语句中的 CAST 可能在 ISDATE 0 之前执行。

修改语句:

SELECT * FROM (SELECT MyDate, CAST(MyDate AS DATETIME) AS MyDate_Mod FROM MyTable
    WHERE ISDATE(MyDate) <> 0 AND MyDate NOT LIKE '__/__/____') AS Sub
WHERE YEAR(Sub.MyDate_Mod) >= 2000

这也失败了。

如果它正在寻找有效的 ISDATE(MyDate),有人可以向我解释为什么它失败了吗?

【问题讨论】:

    标签: tsql


    【解决方案1】:

    仍然不允许发表评论(但将其视为一个)。对于第三个查询,您是否尝试过类似的操作:

    SELECT Top 10 Sub.*, Datepart(year,Sub.MyDate_Mod)
    FROM 
        (SELECT MyDate, CAST(MyDate AS DateTime) AS MyDate_Mod
         FROM MyTable
         WHERE ISDATE(MyDate) <> 0 AND MyDate NOT LIKE '__/__/____') AS Sub
    

    这只是为了看看你是否得到任何结果,或者它是否总是抛出错误。如果可行,请尝试将其移至 WHERE 子句。

    【讨论】:

    • 我试过了,效果很好。但是,如果我将 Datepart() 放入 WHERE 子句,它会失败并出现相同的转换错误。奇怪!!!
    • 再次好奇,如果您也嵌套了该 select 语句,那么您只需执行 select * from... where alias_for_date_part >= 2000 会起作用吗?并不是说它是最干净的代码,但这很奇怪。
    • 我的假设是 SQL 执行计划器将语句分开并将其重新排序到最佳级别(对其视图)并以某种方式稍后执行 ISDATE。
    猜你喜欢
    • 1970-01-01
    • 2014-06-07
    • 1970-01-01
    • 2014-06-08
    • 1970-01-01
    • 2019-12-23
    • 2019-03-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多