Как SQL Server определяет формат неявного преобразования datetime?
declare @str_datetime varchar(50)
set @str_datetime='30-04-2012 19:01:45' -- 30th April 2012
declare @dt_datetime datetime
select @dt_datetime=@str_datetime
Это дает следующую ошибку:
Msg 242, Уровень 16, Состояние 3, Строка 4
преобразование varchar типа данных в тип данных datetime в результате вне диапазона значение.
мой вопрос в том, как SQL Server решает, какой формат использовать для неявного преобразования datetime?
3 ответов
это может зависеть от различных факторов - региональных настроек операционной системы, языка текущего пользователя и параметров dateformat. По умолчанию, Windows использует US English
и настройки US English
и MDY
.
но вот несколько примеров, чтобы показать, как это можно изменить.
пользователь использует настройки английского языка:
-- works:
SET LANGUAGE BRITISH;
SELECT CONVERT(DATETIME, '30-04-2012 19:01:45');
-- fails:
SELECT CONVERT(DATETIME, '04/13/2012');
GO
(ошибка)
Msg 242, Уровень 16, Состояние 3, Строка 5
преобразование a данных varchar тип в тип данных datetime в результате вне диапазона значение.
пользователь использует Français:
-- works:
SET LANGUAGE FRENCH;
SELECT CONVERT(DATETIME, '30-04-2012 19:01:45');
-- fails:
SELECT CONVERT(DATETIME, '04/13/2012');
GO
(ошибка)
Msg 242, Уровень 16, Состояние 3, Строка 1
La преобразование d'un type de données varchar en type de données datetime a créé une valeur hors по limites.
пользователь снова использует Français:
SET LANGUAGE FRENCH;
-- fails (proving that, contrary to popular belief, YYYY-MM-DD is not always safe):
SELECT CONVERT(DATETIME, '2012-04-30');
GO
(ошибка)
Msg 242, Уровень 16, Состояние 3, строка 1
La преобразование d'un type de données varchar en type de données datetime a créé une valeur hors limites.
пользователь использует DMY вместо MDY:
SET LANGUAGE ENGLISH;
SET DATEFORMAT DMY;
-- works:
SELECT CONVERT(DATETIME, '30-04-2012 19:01:45');
-- fails:
SELECT CONVERT(DATETIME, '04-30-2012');
GO
(ошибка)
Msg 242, Уровень 16, Состояние 3, Строка 2
преобразование varchar типа данных в тип данных datetime в результате вне диапазона значение.
ваш лучший выбор, всегда, использовать стандарт ИСО, не-региональный, безопасный, однозначные форматы дат. Два, которые я обычно рекомендую:
YYYYMMDD - for date only.
YYYY-MM-DDTHH:MM:SS[.mmm] - for date + time, and yes that T is important.
ни один из них не терпит неудачу:
SET DATEFORMAT MDY;
SET LANGUAGE ENGLISH;
SELECT CONVERT(DATETIME, '20120430');
SELECT CONVERT(DATETIME, '2012-04-30T19:01:45');
SET LANGUAGE FRENCH;
SELECT CONVERT(DATETIME, '20120430');
SELECT CONVERT(DATETIME, '2012-04-30T19:01:45');
SET LANGUAGE BRITISH;
SELECT CONVERT(DATETIME, '20120430');
SELECT CONVERT(DATETIME, '2012-04-30T19:01:45');
SET DATEFORMAT DMY;
SELECT CONVERT(DATETIME, '20120430');
SELECT CONVERT(DATETIME, '2012-04-30T19:01:45');
поэтому я настоятельно рекомендую вместо того, чтобы позволять пользователям вводить форматы даты свободного текста (или использовать ненадежные форматы самостоятельно), контролировать входные строки и убедиться, что они придерживаются одного из этих безопасных форматов. Тогда не будет иметь значения, какие настройки у пользователя есть или каковы основные региональные настройки, ваши даты всегда будут интерпретироваться как они должны были быть датами. Если вы разрешаете пользователям вводить даты в текстовое поле формы, прекратите это делать и реализуйте элемент управления calendar или, по крайней мере, список выбора, чтобы в конечном итоге можно было управлять строковым форматом, возвращаемым SQL Server.
для некоторого фона, пожалуйста, прочитайте Тибора Карасци "окончательное руководство по типам данных datetime" и мой пост "вредные привычки, чтобы пнуть: Mis-обработка запросов даты / диапазона."
по умолчанию формат даты для SQL server находится в формате даты США MM/DD / YY, если не установлена локализованная версия SQL Server. Этот параметр подходит для случаев, когда приложение, требующее этого функциональность развертывается таким образом, чтобы гарантировать использование дат и вставляется в том же формате на всех платформах и местах где используется приложение.
однако в некоторых случаях дата должна быть в DD / MM/YY формат, потому что многие страны / регионы используют этот формат, а не дефолт США MM/DD / YY. Особенно это касается международных заявок они распространены по всему миру.
Итак, вам нужно установить формат даты перед рукой так:
SET DATEFORMAT dmy
GO
и тогда ваш запрос будет работать.
вы также можете изменить формат даты по умолчанию для каждого входа и / или для каждого будущего добавленного входа (без необходимости делать "SET DATEFORMAT" в каждом сеансе.
вы идете в SQL Management Studio / Security / логины. Справа-clic логин, затем Свойства. Вы увидите "язык по умолчанию" в нижней части.
Если вы хотите убедиться, что любые логины, добавленные в будущем, получат "хороший" язык. Щелкните правой кнопкой мыши корень сервера, затем Свойства и расширенную страницу. Есть опция "язык по умолчанию" там тоже используется для вновь созданных Логинов.