Is there a function like isdate() for datetime2?

送分小仙女□ 提交于 2020-07-20 07:46:14

问题


I know there is a function called ISDATE to validate DATETIME columns, but it works only for the SMALLDATETIME and DATETIME types.

Is there a similar way to validate the new data type DATETIME2 in SQL Server 2008 and 2012?


回答1:


In SQL Server 2012, you can use TRY_CONVERT:

SELECT TRY_CONVERT(DATETIME2, '2012-02-02 13:42:55.2323623'),
       TRY_CONVERT(DATETIME2, '2012-02-31 13:42:55.2323623');

Results:

2012-02-02 13:42:55.2323623    NULL

Or 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);

(Same results.)

Sorry that I don't have a clever answer for you for < SQL Server 2012. You could, I guess, say

SELECT ISDATE(LEFT('2012-02-02 13:42:55.2323623', 23));

But that feels dirty.

TRY_CONVERT documentation on Microsoft Docs
TRY_PARSE documentation on Microsoft Docs




回答2:


Be careful using the LEFT(..., 23) solution on database systems using another dateformat than mdy (and SQL-Server 2008). You can see the dateformat of the current session using the DBCC USEROPTIONS command.

On a database system using the german dateformat (dmy) the LEFT(..., 23) solution isn't working (detected on dates with day > 12). See the following test case:

-- 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;

How to solve that?

You can use a CAST(column_name AS DATETIME) instead of the LEFT(..., 23) to make this work:

-- 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;

demo on dbfiddle.uk (using dmy) / demo on dbfiddle.uk (using mdy)


On SQL Server 2012 and later you should use the TRY_PARSE / TRY_CONVERT solution described in @Aaron Bertrand answer. The CAST(... AS DATETIME) solution explained in this answer should also work.



来源:https://stackoverflow.com/questions/11043981/is-there-a-function-like-isdate-for-datetime2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!