问题描述
我有一列需要将数据转换为DATE格式。每当我遇到数据“ MM / YYYY / DD”格式时,都会收到以下错误消息,但对于其他格式也可以正常工作。
从字符串转换日期和/或时间时转换失败
样本数据:
SELECT CAST('05/2020/29' AS DATE);
SELECT ISDATE('05/2020/29')
返回1
,但是CAST
或CONVERT
函数失败。
解决方法
那是一个奇怪的格式。我会推荐datefromparts()
:
select datefromparts(
substring(mycol,4,4),left(mycol,2),right(mycol,2)
) mydate
from mytable
with mytable as (select '05/2020/29' mycol)
select datefromparts(substring(mycol,2)) mydate
from mytable
| mydate | | :--------- | | 2020-05-29 |,
我必须承认,格式MM/yyyy/dd
是日期格式的一种比较奇怪的选择。但是,原因是问题在于,您将日期(和时间)数据存储在varchar
中。
但是,为此,我可以将数据重新排列为ISO格式(yyyyMMdd
),然后重新排列为CONVERT
:
SELECT TRY_CONVERT(date,CONCAT(SUBSTRING(YourString,LEFT(YourString,RIGHT(YourString,2)),112)
FROM dbo.YourTable;
我在这里使用TRY_CONVERT
是因为经验已证明了无数次,那些将日期(和时间)数据作为varchar
存储在数据库中的数据也以错误数据结尾(例如'13/2020/11'
适合您的风格)。这意味着当遇到这些不良行并返回NULL
时,转换不会失败。
但是,理想情况下,您应该修复列并更改数据类型。实际上,我们可以使用与上述类似的解决方案来执行此操作。首先,将列中的值更改为ISO格式,但以varchar
的形式,测试转换,然后更改数据类型:
UPDATE YT
SET YT.YourString = CONVERT(varchar(8),V.YourDate,112)
FROM dbo.YourTable YT
CROSS APPLY (VALUES(TRY_CONVERT(date,112)))V(YourDate);
ALTER TABLE dbo.YourTable ALTER COLUMN YourString date NULL;
旁注,ISDATE
是一个可怕的功能,就像它的“同级” ISNUMERIC
一样。这两个函数都返回错误的肯定和否定,因此应避免使用。到目前为止,TRY_CONVERT
和TRY_CAST
是更好的选择。
作为一个简单的示例,请注意以下内容返回了以下值:
SET LANGUAGE ENGLISH; --American,not English...
SELECT ISDATE(20200928); --Returns 1
SELECT ISDATE(17); -Returns 0
SELECT ISDATE('09/2020/28'); --Returns 1
现在,让我们尝试一些转换:
SELECT CONVERT(datetime,20200928); --ISDATE returned 1
将表达式转换为数据类型为datetime的算术溢出错误。
SELECT CONVERT(datetime,17); --ISDATE returned 0
成功,返回datetime
1900-01-18T00:00:00.000
。
SELECT CONVERT(datetime2(0),'09/2020/28'); --ISDATE returned 1
,从字符串转换日期和/或时间时转换失败。
您可以尝试先指定日期格式:
SET DATEFORMAT MYD;
SELECT CAST('05/2020/29' AS DATE);