Недетерминированное преобразование строк дат литералов в значения 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 для детерминированного управления преобразованиями даты. Каждый месяц эта статья имеет наибольшее количество просмотров.

Уровень совместимости 90 и выше

В SQL Server 2000 уровень совместимости был 80. Для уровней 80 и ниже неявные преобразования даты были детерминированными.

Начиная с SQL Server 2005 и уровня совместимости 90, неявные преобразования даты стали недетерминированными. Преобразования даты стали зависеть от SET LANGUAGE и SET DATEFORMAT, начиная с уровня 90.

Юникод

Преобразование символьных данных между различными параметрами сортировки не в Юникоде также считается недетерминированным.

См. также раздел