Не вдалося перетворити дату та / або час із символьного рядка під час вставлення часу


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 у дату

Потім я спробував нижче формат як один із публікацій, запропонованих нашим 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/…, перш ніж ставити це питання. Вони попросили нас використовувати значення 'insert table1 (approvaldate) (convert (datetime, '18 -06-12 10:34:09 PM', 5)) ' але це не працює
Марія

Відповіді:


163

SQL Server підтримує багато форматів - дивіться книги MSDN Online 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 підтримується частково. Він не підтримує зулуський час, незважаючи на те, що він згадується в документації. Це, мабуть, якесь налаштування, я не встиг з’ясувати, але, якщо хтось має таку ж проблему, майте це на увазі.
Michał

3
Я можу підтвердити, що формат дати "YYYYMMDD" працює нормально, спробував це на SQL Server 2014, як спосіб вказати буквальну дату в пункті WHERE. Багато танків до @marc_s
Джорджіо Барчізі

1
Справа DATETIME2 працювала на мене. У моєму випадку я імпортував сценарій бази даних з SQLServer англійською мовою на іспанську версію, тому щоразу одна і та ж помилка. Я просто замінив у сценарії всі "як DATETIME" валюти на "як 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)". Саме з цієї причини я отримував цю помилку. Ця відповідь враховує найпоширенішу причину цієї помилки, що інші відповіді не мали.
ПершийФрактал

1
Я імпортував дані з листа Excel, де нульові значення насправді мали "NULL" у комірці. Це було встановлено як рядок "Null" в таблиці БД, тому намагався перетворити рядок "Null" в дату. Потрібно було випорожнити клітини "NULL" в Excel. Я ідіот: /
karol

17

Проста відповідь - 5 - італійський "yy", а 105 - італійський "yyyy". Тому:

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
Дуже дякую, так, ви праві, це вирішує мою проблему, і я прочитав інші відповіді, наведені тут
Pronab Roy

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-Server добре знає, що робити речі в порядку виконання, якого, можливо, не очікували. Ваше письмове твердження виглядає так, що перетворення зроблено раніше відбудуться певні дії, пов'язані з типом, але двигун вирішує - навіщо взагалі - робити перетворення на наступному кроці.

Ось чудова стаття, що пояснює це на прикладах: Rusano.com: "t-sql-функции-do-no-imply-a-определен-order-of-исполнение", і ось відповідне питання .


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
Якщо ви використовуєте зворотні посилання, а не початкові пробіли, ви отримаєте обговорення слів.
Jesse W at Z -

2

Формат дати, який фактично працює на сервері sql, є

yyyy-mm-dd hh:MM:ss

1
Ні, це неправда (крім невідповідності mта M). Прочитайте коментар Дена Гузмана до відповіді Пронаба Роя. А інші відповіді читайте тут ...
Шнуго

2

Будь ласка, спробуйте це.

SQL Server очікує дат у форматі MM / DD / YYYY, якщо англійською мовою встановлено мову за замовчуванням. Зберігаю значення вибору дати в базі даних sql2008. Мій тип поля - це дата в базі даних.

           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

У мене виникло це питання при спробі об'єднання 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" />

наприклад, якщо ви встановите культуру на арабську, це буде

22/09/2017 02:16:57 ص

і ви отримуєте помилку: Не вдалося перетворити під час перетворення дати та / або часу з символьного рядка під час вставлення часу



Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.