Недетерминированное преобразование строк дат литералов в значения DATE
Применимо к: SQL Server Azure SQL DatabaseУправляемый экземпляр SQL AzureAzure Synapse AnalyticsAnalytics Platform System (PDW)
Будьте осторожны, когда разрешаете преобразование строк CHARACTER в тип данных DATE. Дело в том, что такие преобразования часто бывают недетерминированными.
Вы управляете этими недетерминированными преобразованиями, учитывая параметры SET LANGUAGE и SET DATEFORMAT.
Пример SET LANGUAGE: название месяца на польском языке
SET LANGUAGE Polish;
Строка символов может быть названием месяца. Но это название на английском, польском, хорватском или другом языке? В сеансе пользователя будет настроен соответствующий язык?
Например, рассмотрим слово listopad, являющееся названием месяца. Но какой это месяц, зависит от языка, который используется, по мнению системы SQL:
- Если польский, то listopad — это 11-й месяц (ноябрь).
- Если хорватский, то listopad — это 10-й месяц (ноябрь).
Пример кода SET LANGUAGE
--SELECT alias FROM sys.syslanguages ORDER BY alias;
DECLARE @yourInputDate NVARCHAR(32) = '28 listopad 2018';
SET LANGUAGE Polish;
SELECT CONVERT(DATE, @yourInputDate) AS [SL_Polish];
SET LANGUAGE Croatian;
SELECT CONVERT(DATE, @yourInputDate) AS [SL_Croatian];
SET LANGUAGE English;
/*** Actual output: For the two months, note the 11 versus the 10.
SL_Polish
2018-11-28
SL_Croatian
2018-10-28
***/
Пример SET DATEFORMAT
SET DATEFORMAT dmy;
Предыдущий формат ДМГ указывает, что пример строки даты "01-03-2018" будет интерпретироваться как первый день марта 2018 года.
Если указан формат МДГ, то "01-03-2018" означает третий день января 2018 года.
И если был указан ymd , нет никакой гарантии того, какие будут выходные данные. Числовое значение "2018" слишком велико, чтобы быть днем.
Конкретные страны и регионы
В Японии и Китае используется формат DATEFORMAT ГМД. Части этого формата расположены от большего к меньшему. Таким образом, этот формат хорошо сортируется. Этот формат считается международным форматом. Это международный, потому что четыре цифры года являются однозначными, и ни одна страна или регион на Земле не использует архаический формат ydm.
В других странах и регионах, таких как Германия и Франция, параметр DATEFORMAT имеет значение dmy, что означает "дд-мм-гггг". Формат dmy не сортируется правильно, но это разумная последовательность от наименьшей единицы к наибольшему.
США и Федеративные Штаты Микронезии — это единственные страны и регионы, использующие mdy, которые не сортируются. Этот формат совпадает с тем, как в английском произносятся даты.
Пример кода SET DATEFORMAT: МДГ и ДМГ
В следующем примере кода Transact-SQL используется та же строка символов даты с тремя разными параметрами DATEFORMAT. При выполнении кода получается результат, показанный в комментарии:
DECLARE @yourDateString NVARCHAR(10) = '12-09-2018';
PRINT @yourDateString + ' = the input.';
SET DATEFORMAT dmy;
SELECT CONVERT(DATE, @yourDateString) AS [DMY-Interpretation-of-input-format];
SET DATEFORMAT mdy;
SELECT CONVERT(DATE, @yourDateString) AS [MDY-Interpretation-of-input-format];
SET DATEFORMAT ymd;
SELECT CONVERT(DATE, @yourDateString) AS [YMD-Interpretation--?--NotGuaranteed];
/*** Actual output:
12-09-2018 = the input.
DMY-Interpretation-of-input-format
2018-09-12
MDY-Interpretation-of-input-format
2018-12-09
YMD-Interpretation--?--NotGuaranteed
2018-12-09
***/
В предыдущем примере кода в последнем примере есть несоответствие между форматом ГМД и входной строкой. Третий узел входной строки представляет числовое значение, слишком большое для дня. Корпорация Майкрософт не гарантирует выходное значение из-за таких несоответствий.
CONVERT предлагает явные коды для детерминированного управления форматами даты
В нашей документации по CAST и CONVERT приводятся явные коды, которые можно использовать с функцией CONVERT для детерминированного управления преобразованиями даты. Каждый месяц эта статья имеет наибольшее количество просмотров.
- CAST и CONVERT (Transact-SQL): стили даты и времени
- CAST и CONVERT (Transact-SQL): некоторые преобразования типа данных даты и времени являются недетерминированными
Уровень совместимости 90 и выше
В SQL Server 2000 уровень совместимости был 80. Для уровней 80 и ниже неявные преобразования даты были детерминированными.
Начиная с SQL Server 2005 и уровня совместимости 90, неявные преобразования даты стали недетерминированными. Преобразования даты стали зависеть от SET LANGUAGE и SET DATEFORMAT, начиная с уровня 90.
Юникод
Преобразование символьных данных между различными параметрами сортировки не в Юникоде также считается недетерминированным.
См. также раздел
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по