Ошибка преобразования при преобразовании даты и / или времени из символьной строки при вставке даты и времени


164

Я пытался создать таблицу следующим образом,

create table table1(date1 datetime,date2 datetime);

Сначала я попытался вставить значения, как показано ниже,

insert into table1 values('21-02-2012 6:10:00 PM','01-01-2001 12:00:00 AM');

Это дало ошибку, сказав:

Невозможно преобразовать varchar в datetime

Затем я попробовал формат ниже, как один из постов, предложенных нашим stackoverflow,

insert into table1 values(convert(datetime,'21-02-2012 6:10:00 PM',5)
                          ,convert(datetime,'01-01-2001 12:00:00 AM',5));

Но я все еще получаю сообщение об ошибке,

Ошибка преобразования при преобразовании даты и / или времени из строки символов

Какие-либо предложения?


2
@Damien_The_Unbeliever, как вы сказали, я уже ссылался на этот пост stackoverflow.com/questions/12957635/… прежде чем задавать этот вопрос. Они попросили нас использовать 'вставка значений table1 (ApproveDate) (convert (datetime, '18 -06-12 10:34:09 PM', 5)); но это не работает
Mari

Ответы:


163

SQL Server поддерживает множество форматов - см. MSDN Books Online на CAST и CONVERT . Большинство из этих форматов зависят от того, какие настройки у вас есть - поэтому эти настройки могут работать несколько раз, а иногда нет.

Способ решить эту проблему - использовать (слегка адаптированный) формат даты ISO-8601 , поддерживаемый SQL Server - этот формат работает всегда - независимо от языка SQL Server и настроек формата даты.

Формат ISO-8601 поддерживается SQL Server в двух вариантах:

  • YYYYMMDDтолько для дат (без временной части); обратите внимание: нет тире! это очень важно! YYYY-MM-DDявляется НЕ зависит от настроек DateFormat в вашем SQL Server и НЕ работать в любых ситуациях!

или:

  • YYYY-MM-DDTHH:MM:SSдля дат и времени - обратите внимание здесь: этот формат имеет тире (но они могут быть опущены) и фиксированный в Tкачестве разделителя между частью даты и времени вашего DATETIME.

Это действительно для SQL Server 2000 и новее.

Так что в вашем конкретном случае - используйте эти строки:

insert into table1 values('2012-02-21T18:10:00', '2012-01-01T00:00:00');

и вы должны быть в порядке (примечание: вам нужно использовать международный 24-часовой формат, а не 12-часовой формат AM / PM).

Альтернативно : если вы используете SQL Server 2008 или новее, вы также можете использовать DATETIME2тип данных (вместо простого DATETIME), и ваш текущий INSERTбудет работать без проблем! :-) DATETIME2намного лучше и намного менее требователен к конверсиям - и в любом случае это рекомендуемые типы данных даты / времени для SQL Server 2008 или новее.

SELECT
   CAST('02-21-2012 6:10:00 PM' AS DATETIME2),     -- works just fine
   CAST('01-01-2012 12:00:00 AM' AS DATETIME2)   -- works just fine  

Не спрашивайте меня, почему вся эта тема такая хитрая и несколько запутанная - так оно и есть. Но с этим YYYYMMDDформатом вам подойдет любая версия SQL Server, а также любые настройки языка и даты в вашем SQL Server.


1
Так же, как примечание, приведение к DATETIME2 также работает с 'YYYY-MM-DDTHH: MM: SSZ' (примечание 'Z' - время Зулу в конце, чтобы обозначить метку времени UTC). Я получил эту ошибку при попытке вставить '2013-12-16T17: 21: 26Z' в поле даты и времени. Просто чтобы уточнить, ISO 8601 поддерживается частично. Это не поддерживает время Зулу, несмотря на то, что это упомянуто в документации. Возможно, это какая-то обстановка, которую я не успел выяснить, но на случай, если у кого-то возникнет такая же проблема, имейте это в виду.
Михал

3
Я могу подтвердить, что формат даты «ГГГГММДД» работает нормально, попробовал его на SQL Server 2014, чтобы указать буквальную дату в предложении WHERE. Много танков для @marc_s
Джорджио Баркиези

1
Дело DATETIME2 сработало для меня. В моем случае я импортировал скрипт базы данных из SQLServer на английском языке в испанскую версию, поэтому каждый раз одна и та же ошибка. Я просто заменил в скрипте все вхождения "as DATETIME" на "as DATETIME2" и проблема решена.
Алехандро дель Рио

24

Преобразование на сервере SQL иногда происходит не из-за используемых форматов даты или времени, а просто потому, что вы пытаетесь сохранить неправильные данные, которые не приемлемы для системы.

Пример:

Create Table MyTable (MyDate);

Insert Into MyTable(MyDate) Values ('2015-02-29');

SQL-сервер выдаст следующую ошибку:

Conversion failed when converting date and/or time from character string.

Причиной этой ошибки является просто отсутствие такой даты (29 февраля) в году (2015).


2
«Причиной этой ошибки является просто отсутствие такой даты (29 февраля) в году (2015)». Именно поэтому я и получил эту ошибку. Этот ответ учитывает наиболее частую причину этой ошибки, которую другие ответы не сделали.
FirstFraktal

1
Я импортировал данные из листа Excel, где нулевые значения фактически имели «NULL» в ячейке. Это было установлено как строка «Null» в таблице БД, поэтому пытался преобразовать строку «Null» в datetime. Должен был опустошить ячейки "NULL" в Excel. Я идиот: /
Кароль

17

Простой ответ - 5 - итальянский "уу", а 105 - итальянский "ууу". Следовательно:

SELECT convert(datetime,'21-02-12 6:10:00 PM',5)

будет работать правильно, но

SELECT convert(datetime,'21-02-12 6:10:00 PM',105)

выдаст ошибку.

Точно так же,

SELECT convert(datetime,'21-02-2012 6:10:00 PM',5)

выдаст ошибку, где как

SELECT convert(datetime,'21-02-2012 6:10:00 PM',105)

буду работать.


8

Просто обновите формат даты, как показано ниже

yyyy-MM-dd hh:MM:ss

Это решает проблему для меня и работает нормально


2
Пожалуйста, прочитайте другие ответы, уже предоставленные. Этот формат работает только из-за DATEFORMATнастроек сеанса . Проверьте это, запустив SET DATEFORMAT MDY;SELECT CAST('2017-08-07 00:00:00' AS datetime); SET DATEFORMAT DMY;SELECT CAST('2017-08-07 00:00:00' AS datetime);. Он будет работать надежно, если вы добавите Tразделитель ( yyyy-MM-ddTHH:mm:ss).
Дан Гузман

1
Большое спасибо, да, вы правы, это решает мою проблему, и я читаю другие ответы, приведенные здесь
Пронаб Рой

8

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

Существует несколько безопасных форматов для предоставления даты / времени в буквальном смысле:

Все примеры для 2016-09-15 17:30:00

ODBC (мой любимый, так как он обрабатывается как настоящий тип сразу)

  • {ts'2016-09-15 17:30:00'} - штамп времени
  • {d'2016-09-15'} - только дата
  • {t'17:30:00'} - Только время

ISO8601 (лучший для всех )

  • '2016-09-15T17:30:00'- знать о Tв середине!

Неразделенный (крошечный риск быть неверно истолкованным как число)

  • '20160915' - только для чистой даты

Хорошо иметь в виду: неверные даты имеют тенденцию появляться со странными ошибками

  • Там нет 31 июня или 30 февраля ...

Еще одна причина странных ошибок конвертации: порядок выполнения!

Хорошо известно, что SQL-сервер работает в том порядке, в котором его нельзя было ожидать. Ваше письменное заявление выглядит так, как будто преобразование сделано раньше какое-либо действие, связанное с типом, но механизм решает - почему вообще - выполнить преобразование на более позднем этапе.

Вот отличная статья, объясняющая это на примерах: Rusano.com: «t-sql-functions-do-no-imply-a-not-as-a-be-as-Order-of-Execution» и вот связанный вопрос .


3

лучший способ это код

"select * from [table_1] where date between convert(date,'" + dateTimePicker1.Text + "',105) and convert(date,'" + dateTimePicker2.Text + "',105)"

2
convert(datetime2,((SUBSTRING( ISNULL(S2.FechaReal,e.ETA),7,4)+'-'+ SUBSTRING( ISNULL(S2.FechaReal,e.ETA),4,2)+'-'+ SUBSTRING( ISNULL(S2.FechaReal,e.ETA),1,2) + ' 12:00:00.127')))  as fecha,

1
Если вы используете обратные пометки, а не начальные пробелы, вы получите перенос слов.
Джесси W в Z - Отказался от SE

2

Формат datetime на самом деле работает на сервере SQL

yyyy-mm-dd hh:MM:ss

1
Нет, это не так (кроме несоответствия mи M). Прочитайте комментарий Дэна Гусмана к ответу Пронаба Роя. И прочитайте другие ответы здесь ...
Shnugo

2

Пожалуйста, попробуйте это.

SQL Server ожидает даты в формате MM / DD / YYYY, если в качестве языка по умолчанию задан английский язык. Здесь я сохраняю значение datepicker в базе данных sql2008. Мой тип поля - datetime в database.dpdob - это мое имя datepicker.

           Dim test = dpdob.Text.Replace("-", "/")
           Dim parts As String() = test.Split(New Char() {"/"c})
           Dim firstPart As String = parts(0)
           Dim thirdPart As String = parts(2)
           Dim secondPart As String = parts(1)
           Dim test1 = secondPart + "/" + firstPart + "/" + thirdPart
           Dim dob = test1

Теперь используйте dob в вашем запросе на вставку.


1

Вы можете попробовать этот код

select (Convert(Date, '2018-04-01'))

1

У меня была эта проблема при попытке объединить getdate() в строку, которую я вставил в поле nvarchar.

Я сделал несколько кастингов, чтобы обойти это:

 INSERT INTO [SYSTEM_TABLE] ([SYSTEM_PROP_TAG],[SYSTEM_PROP_VAL]) VALUES 
   (
    'EMAIL_HEADER',
    '<h2>111 Any St.<br />Anywhere, ST 11111</h2><br />' + 
        CAST(CAST(getdate() AS datetime2) AS nvarchar) + 
    '<br /><br /><br />'
   )

Это санированный пример. Ключевая часть этого:

...' + CAST(CAST(getdate() AS datetime2) AS nvarchar) + '...

Приведена дата как datetime2, так и nvarcharдля конкатенации.



0

установите Культуру на английский из файла web.config

  <globalization uiCulture="en-US" culture="en-US" />

например, если вы установите культуру на арабском языке, thime будет

22.09.2017 02:16:57 ص

и вы получаете ошибку: преобразование не удалось при преобразовании даты и / или времени из символьной строки при вставке даты и времени



Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.