Ответ 2
В SQL Server 2012+ вы можете использовать DATEFROMPARTS
():
DECLARE @Year int = 2016, @Month int = 10, @Day int = 25;
SELECT DATEFROMPARTS (@Year, @Month, @Day);
В более ранних версиях одним из методов является создание и преобразование строки.
Существует несколько форматов строк, которые SQL Server достоверно интерпретирует независимо от настроек даты, языка или интернационализации.
Шесть или восьмизначная строка всегда интерпретируется как ymd. Месяц и день должен быть всегда двухзначным.
https://docs.microsoft.com/en-us/sql/t-sql/data-types/datetime-transact-sql
Таким образом, строка в формате "yyyymmdd" всегда будет правильно интерпретироваться.
(ISO 8601-- YYYY-MM-DDThh:mm:ss
- также работает, но вы должны указать время и, следовательно, сложнее, чем вам нужно.)
Пока вы можете просто CAST
эту строку в качестве даты, вы должны использовать CONVERT
, чтобы указать стиль, и вы должны указать стиль, чтобы быть детерминированным (если это имеет для вас значение).
Формат "yyyymmdd" - это стиль 112, поэтому ваше преобразование выглядит следующим образом:
DECLARE @Year int = 2016, @Month int = 10, @Day int = 25;
SELECT CONVERT(date,CONVERT(varchar(50),(@Year*10000 + @Month*100 + @Day)),112);
И это приводит к:
2016-10-25
Технически формат ISO/112/yyyymmdd работает даже с указанными другими стилями. Например, используя этот текстовый формат со стилем 104 (немецкий, dd.mm.yyyy):
DECLARE @Year int = 2016, @Month int = 10, @Day int = 25;
SELECT CONVERT(date,CONVERT(varchar(50),(@Year*10000 + @Month*100 + @Day)),104);
Также по-прежнему получается:
2016-10-25
Другие форматы не такие надежные. Например:
SELECT CASE WHEN CONVERT(date,'01-02-1900',110) = CONVERT(date,'01-02-1900',105) THEN 1 ELSE 0 END;
Результаты в:
0
В качестве побочного примечания, с помощью этого метода, будьте осторожны, что входы бессмысленного ввода могут давать допустимые, но неправильные даты:
DECLARE @Year int = 2016, @Month int = 0, @Day int = 1025;
SELECT CONVERT(date,CONVERT(varchar(50),(@Year*10000 + @Month*100 + @Day)),112);
Также дает:
2016-10-25
DATEFROMPARTS
защищает вас от недопустимых входов. Это:
DECLARE @Year int = 2016, @Month int = 10, @Day int = 32;
SELECT DATEFROMPARTS (@Year, @Month, @Day);
Урожайность:
Msg 289, Уровень 16, Состояние 1, Строка 2 Невозможно создать дату типа данных, некоторые из аргументов имеют недопустимые значения.
Также помните, что этот метод не работает для дат до 1000-01-01. Например:
DECLARE @Year int = 900, @Month int = 1, @Day int = 1;
SELECT CONVERT(date,CONVERT(varchar(50),(@Year*10000 + @Month*100 + @Day)),112);
Урожайность:
Msg 241, уровень 16, состояние 1, строка 2 Преобразование не удалось при преобразовании дату и/или время от символьной строки.
Это потому, что результирующая строка "9000101" не находится в формате "yyyymmdd" . Чтобы обеспечить правильное форматирование, вам придется прокладывать его с помощью ведущих нулей при жертве небольшого количества производительности. Например:
DECLARE @Year int = 900, @Month int = 1, @Day int = 1;
SELECT CONVERT(date,RIGHT('000' + CONVERT(varchar(50),(@Year*10000 + @Month*100 + @Day)),8),112);
Результаты в:
0900-01-01
Существуют другие методы, помимо преобразования строк. Некоторые из них приводятся в ответах на "Создать дату с T-SQL". Примечательный пример включает в себя создание даты путем добавления лет, месяцев и дней к "нулевой дате".
(Этот ответ был вдохновлен ответом Гордоном Линоффом, который я расширил и предоставил дополнительную документацию и примечания.)