我知道有一个调用ISDATE
来验证DATETIME
列的函数,但它仅适用于SMALLDATETIME
andDATETIME
类型。
是否有类似的方法来验证DATETIME2
SQL Server 2008 和 2012 中的新数据类型?
我知道有一个调用ISDATE
来验证DATETIME
列的函数,但它仅适用于SMALLDATETIME
andDATETIME
类型。
是否有类似的方法来验证DATETIME2
SQL Server 2008 和 2012 中的新数据类型?
在 SQL Server 2012 中,您可以使用TRY_CONVERT
:
SELECT TRY_CONVERT(DATETIME2, '2012-02-02 13:42:55.2323623'),
TRY_CONVERT(DATETIME2, '2012-02-31 13:42:55.2323623');
结果:
2012-02-02 13:42:55.2323623 NULL
或者TRY_PARSE
:
SELECT TRY_PARSE('2012-02-02 13:42:55.2323623' AS DATETIME2),
TRY_PARSE('2012-02-31 13:42:55.2323623' AS DATETIME2);
(结果相同。)
抱歉,对于< SQL Server 2012,我没有给你一个聪明的答案。我想你可以说
SELECT ISDATE(LEFT('2012-02-02 13:42:55.2323623', 23));
但这感觉很脏。
LEFT(..., 23)
在使用另一种日期格式mdy
(和 SQL-Server 2008)的数据库系统上使用该解决方案时要小心。DBCC USEROPTIONS
您可以使用该命令查看当前会话的日期格式。
在使用德语 dateformat ( dmy
) 的数据库系统上,该LEFT(..., 23)
解决方案不起作用(在 day > 12 的日期检测到)。请参阅以下测试用例:
-- test table using a DATETIME and DATETIME2 column.
CREATE TABLE dt_vs_dt2 (
dt DATETIME,
dt2 DATETIME2
);
-- set a datetime values with a day > 12.
DECLARE @date_value AS DATETIME = DATEADD(DAY, 18 - DAY(GETDATE()), GETDATE());
-- insert the current date into both columns using GETDATE.
-- note: using the following on a day > 12
INSERT INTO dt_vs_dt2 VALUES (@date_value, @date_value);
-- let's have a look at the values.
-- the values look the same (the datetime2 is more precise as expected).
SELECT dt, dt2 FROM dt_vs_dt2;
-- now we expect both values are valid date values.
-- to validate the datetime2 value, the LEFT(..., 23) solution is used.
SELECT ISDATE(dt), ISDATE(LEFT(dt2, 23))
FROM dt_vs_dt2;
如何解决?
您可以使用 aCAST(column_name AS DATETIME)
而不是 theLEFT(..., 23)
来完成这项工作:
-- using a CAST(... AS DATETIME) instead of `LEFT(..., 23)` seems to work.
SELECT dt, CAST(dt2 AS DATETIME) AS dt2
FROM dt_vs_dt2;
-- now both values are valid dates.
SELECT ISDATE(dt) AS dt, ISDATE(CAST(dt2 AS DATETIME)) AS dt2
FROM dt_vs_dt2;
dbfiddle.uk 上的演示(使用dmy
) /dbfiddle.uk上的演示(使用mdy
)
在 SQL Server 2012 及更高版本上,您应该使用@Aaron Bertrand answer中描述的TRY_PARSE
/解决方案。此答案中解释的解决方案也应该有效。TRY_CONVERT
CAST(... AS DATETIME)