У нас установлен экземпляр SQL Server 2008R2 с английским языком (США). SSMS> Экземпляр> Свойства> Общие.
У нас есть логин с языком по умолчанию "британский английский". SSMS> Безопасность> Вход в систему> Пользователь> Свойства.
Внешнее приложение .NET Core генерирует оператор вставки (EF) через форму / веб-API, который создает системную хранимую процедуру sp_executesql с использованием имени входа, установленного выше.
Используя SQL Server Profiler, я вижу, что сгенерированный SQL вставки содержит строковые даты в формате 'yyyy-mm-dd'.
Например "2019-01-15 10:59:19.410"
.
Перед выполнением оператора существует exec sp_reset_connection, за которым следуют следующие операторы SET (я полагаю, это как-то связано с совместным использованием пула соединений для обеспечения правильных настроек для каждого входа в систему).
-- network protocol: LPC
set quoted_identifier on
set arithabort off
set numeric_roundabort off
set ansi_warnings on
set ansi_padding on
set ansi_nulls on
set concat_null_yields_null on
set cursor_close_on_commit off
set implicit_transactions off
set language British
set dateformat dmy
set datefirst 1
set transaction isolation level read committed
Что меня смущает, так это то, что оператор выполняется успешно, хотя в формате yyyy-mm-dd
есть даты, а среда настроена как британский английский (DMY). Например - "2019-01-15 10:59:19.410"
.
Я узнал, что «2019-01-15 10: 59: 19.410» будет интерпретироваться как 1-й день 15-го месяца 2019 года, если DMY является текущей настройкой.
Например, это не удастся, так как SQL попытается интерпретировать строку даты как гггг-дд-мм
SET LANGUAGE [British English];
SELECT
CAST('2019-01-13' AS DATETIME);
Сообщение 242, Уровень 16, Состояние 3, Строка 3 Преобразование данных varchar
тип в тип данных datetime, приведший к значению вне допустимого диапазона.
Установка языка на английский (us_english) изменяет интерпретацию строки на MDY, и вышеуказанное утверждение работает.
Мне известно, что я могу использовать не двусмысленные строки даты, но у меня возникла проблема, связанная со строками даты, генерируемыми интерфейсом EF.
Я не могу понять, почему оператор выполняется успешно. Очевидно, что существуют неявные приведения из строк даты в типы DATETIME.
Если я скопирую оператор из профилировщика SQL и вставлю в SSMS и попытаюсь выполнить для той же базы данных / того же пользователя, то произойдет сбой, как я и ожидал.
Сообщение 8114, уровень 16, состояние 1, строка 14 Ошибка преобразования типа данных
varchar на сегодняшний день.
Итак ...
Я понимаю, что происходит при преобразовании строковых дат в тип DATETIME, и получаю согласованные результаты при выполнении запросов в SSMS, но не могу понять, почему запрос, который не выполняется в SSMS, выполняется из внешнего интерфейса.
Я прошу прощения, если это не очень хорошо объяснено.