Есть ли такая функция, как isdate() для datetime2?
Я знаю, что есть функция isdate() для проверки столбцов datetime, но она работает только для типов smalldatetime и datetime. Вопрос: есть ли аналогичный способ проверки нового типа данных datetime2 в SQL Server 2008 и 2012?
1 ответ
В 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);
(Те же результаты.)
Извините, что у меня нет умного ответа для вас за < 2012 год. Я думаю, вы могли бы сказать
SELECT ISDATE(LEFT('2012-02-02 13:42:55.2323623', 23);
Но это кажется грязным.
TRY_CONVERT
документация по MSDNTRY_PARSE
документация по MSDN
Будьте осторожны, используя LEFT(..., 23)
решение в системах баз данных с использованием другого формата даты, чем mdy
(и SQL-Server 2008). Вы можете увидеть формат даты текущего сеанса, используя DBCC USEROPTIONS
команда.
В системе баз данных с использованием немецкого формата даты (dmy
) LEFT(..., 23)
решение не работает (обнаружено в даты с днем> 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;
Как это решить?
Вы можете использовать CAST(column_name AS DATETIME)
вместо LEFT(..., 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
) / demo на dbfiddle.uk (используя mdy
)
На SQL Server 2012 и более поздних версиях вы должны использовать TRY_PARSE
/ TRY_CONVERT
Решение, описанное в ответе Аарона Бертран. CAST(... AS DATETIME)
Решение, объясненное в этом ответе, также должно работать.