如何在 SQL 服务器中将 MM/YYYY/DD 格式字符串转换为 DATE?

How to convert MM/YYYY/DD format string to DATE in SQL Server?

我有一列需要将数据转换为 DATE 格式。每当我遇到数据 'MM/YYYY/DD' 格式时,我都会收到以下错误,但它适用于其他格式。

Conversion failed when converting date and/or time from character string

示例数据:

SELECT CAST('05/2020/29' AS DATE);

SELECT ISDATE('05/2020/29') returns 1CASTCONVERT 函数失败。

这是一种奇怪的格式。我会推荐 datefromparts():

select datefromparts(
    substring(mycol, 4, 4), 
    left(mycol, 2), 
    right(mycol, 2)
) mydate
from mytable

Demo on DB Fiddle:

with mytable as (select '05/2020/29' mycol)
select datefromparts(substring(mycol, 4, 4), left(mycol, 2), right(mycol, 2)) mydate
from mytable
| mydate     |
| :--------- |
| 2020-05-29 |

我必须承认,格式 MM/yyyy/dd 是一种相当奇怪的日期格式选择。然而,问题在于您将日期(和时间)数据存储在 varchar.

然而,为此,我可以将数据重新排列为 ISO 格式 (yyyyMMdd),然后 CONVERT:

SELECT TRY_CONVERT(date,CONCAT(SUBSTRING(YourString,4,4),LEFT(YourString,2),RIGHT(YourString,2)),112)
FROM dbo.YourTable;

我在这里使用 TRY_CONVERT 因为经验无数次证明那些将日期(和时间)数据作为 varchar 存储在数据库中的数据最终也会得到错误的数据(比如 '13/2020/11'适合你的风格)。这意味着当遇到这些坏行并且 NULL 被 return 代替时,转换不会失败。

不过,理想情况下,您应该修复您的列并更改数据类型。我们实际上可以使用与上述类似的解决方案来做到这一点。首先将列中的值更改为 ISO 格式,但作为 varchar,并测试转换,然后更改数据类型:

UPDATE YT
SET YT.YourString = CONVERT(varchar(8),V.YourDate,112)
FROM dbo.YourTable YT
     CROSS APPLY (VALUES(TRY_CONVERT(date,CONCAT(SUBSTRING(YourString,4,4),LEFT(YourString,2),RIGHT(YourString,2)),112)))V(YourDate);

ALTER TABLE dbo.YourTable ALTER COLUMN YourString date NULL;

附带说明,ISDATE 是一个糟糕的函数,就像它的“兄弟”ISNUMERIC。这两个函数 return 误报和漏报,应该避免。 TRY_CONVERTTRY_CAST 是目前更好的选择。

举个简单的例子,请注意以下值 returned 用于以下内容:

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

Arithmetic overflow error converting expression to data type datetime.

SELECT CONVERT(datetime,17); --ISDATE returned 0

成功,returns datetime 1900-01-18T00:00:00.000

SELECT CONVERT(datetime2(0),'09/2020/28'); --ISDATE returned 1

Conversion failed when converting date and/or time from character string.

您可以尝试先指定日期格式:

SET DATEFORMAT MYD;
SELECT CAST('05/2020/29' AS DATE);