问题
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