Это очень плохая привычка хранить значения даты и времени в строке. Причина: форматы даты и времени отличаются во всем мире и зависят от настроек вашей системы. Еще хуже, некоторые форматы зависят от данного языка. Попробуйте это:
SET LANGUAGE ENGLISH; --try with GERMAN to see the effect on "Decemeber"
SET DATEFORMAT ymd; --try with "ydm" or "dmy"
DECLARE @tbl TABLE(dob NVARCHAR(MAX));
INSERT INTO @tbl VALUES('blah') --just a wrong value
,('20201231') --ISO, "unseparated YMD-format (see CONVERT with 112)
,('2020-12-31') --ISO8601
,('2020-31-12') --European with leading year
,('12-31-2020') --USA (see CONVERT with 110)
,('31-12-2020') --European (see CONVERT with 113)
,('31 December 2020') --language dependant (see CONVERT with 113), try with German "Dezember"
,('2020-02-30'); --Invalid, there's no 30th of February
SELECT t.dob --Your value
,[cast] = TRY_CAST(t.dob AS DATETIME) --CAST relies on the system's settings (might work on your machine but can break on a customer's machine
,[convert] = TRY_CONVERT(DATETIME, t.dob, 112) --CONVERT allows to use the style paramter, better than CAST, but more strict
,[parse] = TRY_PARSE(t.dob AS DATETIME USING 'en-US') --Parsing allows to mention the culture. You do not need to specify the language as a general setting
,[xmlCast] = CAST(t.dob AS XML).value('. cast as xs:date?','datetime') --Works below v2012, but can deal with ISO8601 only.
FROM @tbl t;
Играть с настройками
Вы можете использовать GERMAN
вместо ENGLISH
. Запись с December
больше не будет работать. Вы можете изменить общий формат даты на любую комбинацию ymd
и обнаружить, что некоторые форматы перестают работать, а другие начинают работать.
TRY_CAST
, TRY_CONVERT
и TRY_PARSE
потребуется версия версии v2012 или выше.
Если вы используете более старую систему, вам следует выполнить обновление (:-)). Единственный шанс для более старой системы - взломать XML, но это очень тесно связано с ISO8601.
Наконец: для вашего следующего вопроса, пожалуйста, попробуйте добавить больше информации. Укажите некоторые из ваших входных значений, укажите вашу СУБД с версией и попробуйте настроить макет с DDL и INSERT (посмотрите, что я сделал выше).
Подсказка: очень опасно. ..
Попробуйте ввести значение, например 2020-05-06
, и вы обнаружите, что некоторые стили читают это как 5 июня, а другие возвращают 6 мая. Возвращать неправильные значения хуже , чем возвращать NULL или выдавать ошибку ...
StayAtHome
StayHealthy