Есть ли такая функция, как 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 документация по MSDN
TRY_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) Решение, объясненное в этом ответе, также должно работать.

Другие вопросы по тегам