SQL Server - 值通过 ISDATE() 但无法 CAST 为 DATE 或 DATETIME

问题描述 投票:0回答:4

我的数据库表中有一个

varchar
列,在我想要返回的行上,它填充为“
2018-12-26T00:00:00.000
”(引用我的,不包含在实际值中)。当我尝试在有效日期时查询该值时,例如

SELECT
    myValue
FROM 
    myTable
WHERE
    ISDATE(myValue) = 1

它正确返回。但是,我需要将此值转换为

DATE
。当我尝试这样的事情时:

SELECT
    CAST(myValue AS DATE) AS myValueFormatted
FROM 
    myTable
WHERE
    ISDATE(myValue) = 1

我收到错误

从字符串转换日期和/或时间时转换失败

有没有其他方法可以将此

varchar
值转换为
Date

更新:我注意到通过尝试一些不同的事情,查询似乎适合我在选择部分中使用该值作为任何内容的日期(

DATEDIFF
CONVERT
返回字符串等),但是尝试在
WHERE
子句中对其执行任何操作都会导致错误。为了确保没有其他干扰,我创建了一个临时表,其中只有 1 行包含上面的数据值,并且仅针对该一个值运行查询会给出错误

更新 2:好的,我不知道为什么会修复它,但这就是我发现的。当我跑步时

SELECT
    myValue
FROM
    myTable
WHERE
    TRY_CONVERT(DATE, myValue) IS NOT NULL

它返回与

完全相同的值
SELECT
    myValue
FROM 
    myTable
WHERE
    ISDATE(myValue) = 1

但是,当我将

AND CAST(myValue AS DATE) < GETDATE()
添加到每个
WHERE
子句时,只有第一个有效。我明白为什么 TRY_CONVERT 使用起来更安全,但我仍然不确定为什么它比 GETDATE() 更有效

sql sql-server casting type-conversion
4个回答
3
投票

我无法重现你的错误...

declare @dt varchar(256) = '2018-12-26T00:00:00.000'
select cast(@dt as date)

所以,里面肯定还有另一个无法转换的流氓值。

确定导致版本问题的值 < 2012, run this:

SELECT
myValue
FROM myTable
WHERE
ISDATE(myValue) = 0

注意,仅当与

ISDATE
函数一起使用时,
CONVERT
才是确定性的,并且指定了
CONVERT
样式参数,并且样式不等于 0、100、9 或 109。

从 2012 年起,请使用

TRY_CONVERT

SELECT
*
FROM myTable
WHERE
TRY_CONVERT(date, myValue) IS NULL

0
投票

你也可以尝试这样的事情:

SELECT CAST(LEFT(MyValue, 10) AS DATE)

如果仍然不起作用,则说明您的数据存在一些格式问题。


0
投票

这对我有帮助......

将字符串转换为 varchar(30),然后将 varchar 转换为 datetime2

CAST(CAST(REPLACE(['时间戳'],'''','') AS varchar(30)) as datetime2)


0
投票

当我遇到同样的问题“值通过 ISDATE() 但无法 CAST as DATE”时,我偶然发现了这篇文章

我发现我的专栏中有值“1969-12-031”。

我很困惑为什么这个值会用 ISDATE() 返回 true (1) 但无法 CAST as DATE。日期值肯定是错误的,因为它有 3 位数字

来吧,尝试一下:

SELECT ISDATE('1969-12-31'), ISDATE('1969-12-031'), ISDATE('2023-03-003'), ISDATE('1995-12-100')

第一个显然是有效的,但接下来的两个在 SQL Server 2016 上也返回 1,尽管当天使用了 3 位数字。最后一张,没有混乱,一个月没有100天。

SELECT CAST('1969-12-031' AS Date)

当尝试投射它时,它失败了。

有人出主意吗?

© www.soinside.com 2019 - 2024. All rights reserved.