У меня есть таблица1 с 20 столбцами, один из которых — столбец года как smallint
в формате ГГГГ.
Я хочу вставить его в таблицу2 со столбцом года как Datetime, но в формате даты YYYY
.
insert into table2
(Year)
Select
CONVERT(datetime,convert(varchar(10),year))
from table1
Однако это не сработало из-за ошибки
Ошибка преобразования при преобразовании даты и/или времени из символьной строки.
Какие-либо предложения?
тип DateTime не может быть не только по году (гггг), ему нужна полная дата, так что же вы хотите для месяца, дня, минуты, часа, секунды и миллисекунды?
Задавая вопрос, вам необходимо предоставить минимальный воспроизводимый пример: (1) DDL и образец набора данных, т. е. таблицы CREATE плюс инструкции INSERT T-SQL. (2) Что вам нужно сделать, то есть логику и попытку реализации вашего кода в T-SQL. (3) Желаемый результат, основанный на примере данных в пункте 1 выше. (4) Версия вашего SQL-сервера (ВЫБЕРИТЕ @@version;).
Числа и даты не имеют формата, это двоичные значения. Вы также не можете просто преобразовать одно число в дату — это год, месяц, день? Сервер не может угадать. Если у вас есть год, используйте DATEFROMPARTS
или DATETIMEFROMPARTS
, чтобы создать дату или дату и время.
Спасибо за ответ, однако происходит вот что: я запустил: Выберите DATEFROMPARTS(year,1,1) From table1 или Select DateTimeFromParts (year,1,1,0,0,0,0) From table1, оба показывают результаты ненадолго, затем появляется ошибка: Der date-Datentyp kann nicht erstellt werden, weil einige Argumente über ungültige Werte verfügen. «Тип данных даты не может быть создан, поскольку некоторые аргументы имеют недопустимые значения».
@AlexJ, у тебя, наверное, какие-то странные значения года. Смотрите SELECT MIN(year), MAX(year) from yourtable
. Datetime имеет ограничения на то, насколько маленькой и большой может быть дата.
Да, были отрицательные числа, и я решил эту проблему. Спасибо за ваше время
Вам необходимо указать день и месяц, чтобы это преобразование заработало. попробуйте что-то вроде этого:
declare @table1 table([year] smallint)
insert into @table1(year) values(2024),(2016),(2015),(2023)
Select
CONVERT(datetime,convert(varchar(10),year)+'-01-01')
from @table1
Использование строки почти всегда является неправильным способом сделать это. В данном случае это вдвойне верно, поскольку код даже не использует правильный формат строки. По историческим причинам литералы только для даты в SQL Server должны использовать неразделенный формат без -
дефисов.
На datetime
влияет настройка DATEFIRST
. Использование DATEFROMPARTS
устраняет любую двусмысленность.
+ '0101'
было бы лучше, так как это однозначный формат
Вам нужен DateTimeFromParts():
insert into table2
(Year)
Select
DateTimeFromParts(year, 1, 1, 0, 0, 0, 0)
from table1
Также есть DateFromParts(), если вам просто нужно значение даты (а также параметры для DateTime2, DateTimeOffset и SmallDateTime), но, поскольку в вопросе указано, что у вас есть столбец DateTime, мы позаботимся о том, чтобы типы точно соответствовали.
НЕ используйте для этого строки. Из-за проблем культуры/интернационализации использование строк имеет тенденцию быть намного медленнее и более подвержено ошибкам, чем вы хотели бы или ожидали, с множеством тонких «подводных камней».
Вероятно, вам тоже стоит сохранить пример DATEFROMPARTS
. Я подозреваю, что ОП не знает о типе date
и о том, насколько он может быть полезен.
@PanagiotisKanavos Я обновил эту информацию.
Спасибо за ответ, однако происходит вот что: я запустил: Выберите DATEFROMPARTS(year,1,1) From table1 или Select DateTimeFromParts (year,1,1,0,0,0,0) From table1, оба показывают результаты ненадолго, затем появляется ошибка: Der date-Datentyp kann nicht erstellt werden, weil einige Argumente über ungültige Werte verfügen. «Тип данных даты не может быть создан, поскольку некоторые аргументы имеют недопустимые значения».
@AlexJ Это означает, что в столбце year
есть данные, которые не соответствуют допустимому году. Есть отрицательные числа? NULL
ценности? 0 с?
вы поняли, были отрицательные числа, и я исключил их из запроса. Спасибо. Я приму это как решение
«со столбцом года как Datetime, но в формате даты YYYY».
datetime
нельзя хранить просто как год;datetime
состоит из года, месяца, дня, часа, минуты, секунды и миллисекунд (с точностью до 1/300 секунды). Если вы просто хотите сохранить год, тоsmallint
— наиболее подходящий тип данных. Если вы хотите сохранить полную дату, но отображать только год, это вопрос приложения.