Konwersja nie powiodła się podczas konwersji daty i / lub godziny z ciągu znaków podczas wstawiania daty i godziny

164

Próbowałem utworzyć tabelę w następujący sposób:

create table table1(date1 datetime,date2 datetime);

Najpierw próbowałem wstawić wartości jak poniżej,

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

Popełnił błąd mówiąc:

Nie można przekonwertować varchar na datetime

Następnie wypróbowałem poniższy format jako jeden z postów sugerowanych przez nasz 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));

Ale nadal pojawia się błąd, który mówi:

Konwersja nie powiodła się podczas konwersji daty i / lub godziny z ciągu znaków

Jakieś sugestie?

Mari
źródło
2
@Damien_The_Unbeliever, jak powiedziałeś, odniosłem się już do tego posta stackoverflow.com/questions/12957635/ ... zanim zadałem to pytanie. Poprosili nas o użycie wartości „wstaw tabelę1 (data zatwierdzenia) (konwersja (data-godzina,„ 18-06-12 10:34:09 ”, 5)); ale to nie działa
Mari

Odpowiedzi:

163

Istnieje wiele formatów obsługiwanych przez SQL Server - zobacz MSDN Books Online na temat CAST i CONVERT . Większość z tych formatów zależy od posiadanych ustawień - dlatego te ustawienia mogą czasami działać - a czasami nie.

Sposobem rozwiązania tego problemu jest użycie (nieznacznie dostosowanego) formatu daty ISO-8601, który jest obsługiwany przez SQL Server - ten format działa zawsze - niezależnie od języka SQL Server i ustawień formatu daty .

Format ISO-8601 jest obsługiwany przez SQL Server w dwóch wersjach:

  • YYYYMMDDtylko daty (bez części czasu); uwaga: bez myślników! , to bardzo ważne! NIEYYYY-MM-DD jest niezależne od ustawień formatu daty w serwerze SQL i NIE będzie działać we wszystkich sytuacjach!

lub:

  • YYYY-MM-DDTHH:MM:SSw przypadku dat i godzin - uwaga: ten format zawiera myślniki (ale można je pominąć) i ustalony Tseparator między datą a godziną w pliku DATETIME.

Dotyczy to SQL Server 2000 i nowszych.

Więc w swoim konkretnym przypadku - użyj tych ciągów:

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

i powinno być dobrze (uwaga: w tym celu należy użyć międzynarodowego formatu 24-godzinnego zamiast 12-godzinnego formatu AM / PM).

Alternatywnie : jeśli korzystasz z SQL Server 2008 lub nowszego, możesz również użyć DATETIME2typu danych (zamiast zwykłego DATETIME), a Twój obecny INSERTbędzie działał bez żadnych problemów! :-) DATETIME2jest o wiele lepszy i mniej wybredny pod względem konwersji - i tak jest to zalecane typy danych data / czas dla SQL Server 2008 lub nowszego.

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  

Nie pytajcie mnie, dlaczego cały ten temat jest taki podstępny i nieco zagmatwany - po prostu tak jest. Ale z YYYYMMDDformatem powinno być w porządku dla każdej wersji SQL Server i dla dowolnego ustawienia języka i formatu daty w SQL Server.

marc_s
źródło
1
Uwaga: przesyłanie jako DATETIME2 działa również z „RRRR-MM-DDTHH: MM: SSZ” (uwaga „Z” - czas Zulu na końcu oznaczający znacznik czasu UTC). Wystąpił ten błąd podczas próby wstawienia „2013-12-16T17: 21: 26Z” w polu daty i godziny. Dla wyjaśnienia, ISO 8601 jest obsługiwany częściowo. Nie obsługuje czasu Zulu, mimo że wspomniano o tym w dokumentacji. Prawdopodobnie jest to ustawienie, którego nie miałem czasu rozgryźć, ale jeśli ktoś ma ten sam problem, miej to na uwadze.
Michał
3
Mogę potwierdzić, że format daty „RRRRMMDD” działa dobrze, wypróbowałem go na SQL Server 2014, jako sposób na określenie daty literalnej w klauzuli WHERE. Wiele czołgów na @marc_s
Giorgio Barchiesi
1
Sprawa DATETIME2 zadziałała dla mnie. W moim przypadku importowałem skrypt bazy danych z serwera SQLServer w języku angielskim do jego hiszpańskiej wersji, więc za każdym razem ten sam błąd. Po prostu zamieniłem w skrypcie wszystkie zdarzenia „as DATETIME” na „as DATETIME2” i rozwiązałem problem.
Alejandro del Río,
24

Konwersja na serwerze SQL czasami kończy się niepowodzeniem nie z powodu użytych formatów daty lub czasu. Dzieje się tak tylko dlatego, że próbujesz zapisać nieprawidłowe dane, które nie są akceptowane przez system.

Przykład:

Create Table MyTable (MyDate);

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

Serwer SQL zgłosi następujący błąd:

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

Powodem tego błędu jest po prostu brak takiej daty (29 lutego) w roku (2015).

Ashraf Abusada
źródło
2
„Przyczyną tego błędu jest po prostu brak takiej daty (29 lutego) w roku (2015)”. To był dokładnie powód, dla którego otrzymałem ten błąd. Ta odpowiedź uwzględnia najczęstszą przyczynę tego błędu, a inne odpowiedzi nie.
FirstFraktal
1
Zaimportowałem dane z arkusza Excela, w którym w komórce wartości null faktycznie miały „NULL”. Zostało to ustawione jako ciąg „Null” w tabeli bazy danych, więc próbowano przekonwertować ciąg „Null” na datę i godzinę. Powinien był opróżnić komórki „NULL” w programie Excel. Jestem idiotą: /
karol
17

Prosta odpowiedź - 5 to włoskie „yy”, a 105 to włoskie „yyyy”. W związku z tym:

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

będzie działać poprawnie, ale

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

da błąd.

Również,

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

da błąd, gdzie jak

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

będzie działać.

Raj
źródło
8

Po prostu zaktualizuj format daty, jak poniżej

yyyy-MM-dd hh:MM:ss

Rozwiązuje problem za mnie i działa dobrze

Pronab Roy
źródło
2
Przeczytaj pozostałe odpowiedzi już udzielone. Ten format działa tylko ze względu na DATEFORMATustawienia sesji . Sprawdź to, uruchamiając 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);. Będzie działać niezawodnie, jeśli dodasz Tseparator ( yyyy-MM-ddTHH:mm:ss).
Dan Guzman,
1
Bardzo dziękuję tak, masz rację, rozwiązuje mój problem i przeczytałem inne odpowiedzi podane tutaj
Pronab Roy
8

O ile to możliwe, należy unikać literałów daty / czasu specyficznych dla kultury .

Istnieje kilka bezpiecznych formatów, które pozwalają podać datę / godzinę jako dosłowne:

Wszystkie przykłady dla 2016-09-15 17:30:00

ODBC (mój ulubiony, ponieważ jest traktowany jako prawdziwy typ natychmiast)

  • {ts'2016-09-15 17:30:00'} --Znak czasu
  • {d'2016-09-15'} - Tylko data
  • {t'17:30:00'} - Tylko czas

ISO8601 (najlepsze wszędzie )

  • '2016-09-15T17:30:00'- uważaj Tna środek!

Unseperated (niewielkie ryzyko błędnej interpretacji jako liczby)

  • '20160915' - tylko dla czystej randki

Warto pamiętać: nieprawidłowe daty zwykle pojawiają się z dziwnymi błędami

  • Nie ma 31 czerwca ani 30 lutego ...

Jeszcze jeden powód dziwnych błędów konwersji: kolejność wykonywania!

SQL-Server dobrze wie, że robi rzeczy w kolejności wykonywania, której można by się nie spodziewać. Twoje pisemne oświadczenie wygląda tak, jakby konwersja została wykonana przed jakimś działaniem związanym z typem, ale silnik decyduje - dlaczego kiedykolwiek - o wykonaniu konwersji w późniejszym etapie.

Oto świetny artykuł wyjaśniający to z przykładami: Rusano.com: „t-sql-functions-do-no-imply-a-pewna-kolejność-wykonania” i tutaj jest powiązane pytanie .

Shnugo
źródło
3

najlepszym sposobem jest ten kod

"select * from [table_1] where date between convert(date,'" + dateTimePicker1.Text + "',105) and convert(date,'" + dateTimePicker2.Text + "',105)"
Ahmed Soliman
źródło
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,
ARLE ANDINO
źródło
1
Jeśli użyjesz odwrotnych apostrofów zamiast początkowych spacji, otrzymasz zawijanie wyrazów.
Jesse W at Z - Given up on SE
2

Format daty i godziny faktycznie działający na serwerze sql to

yyyy-mm-dd hh:MM:ss
Bhavya Dhiman
źródło
1
Nie, to nieprawda (poza niedopasowaniem mi M). Przeczytaj komentarz Dana Guzmana do odpowiedzi Pronab Roy. I przeczytaj inne odpowiedzi tutaj ...
Shnugo,
2

Proszę, spróbuj tego.

SQL Server oczekuje dat w formacie MM / DD / RRRR, jeśli angielski jest ustawiony jako język domyślny.Tutaj zapisuję wartość datepicker do bazy danych sql2008.Moje typ pola to datetime w database.dpdob to moja nazwa datapicker.

           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

Teraz użyj dob w zapytaniu wstawiającym.

SwR
źródło
1

Możesz wypróbować ten kod

select (Convert(Date, '2018-04-01'))
Biddut
źródło
1

Wystąpił ten problem, gdy próbowałem połączyć getdate()w ciąg, który wstawiałem do pola nvarchar.

Zrobiłem trochę castingu, aby to obejść:

 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 />'
   )

To odkażony przykład. Kluczowa część to:

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

Przesłano datę jako datetime2, a następnie jako nvarcharkonkatenację.

vapcguy
źródło
1

Wypróbowałem to i działa ze mną:

SELECT CONVERT(date, yourDate ,104)
Abd Abughazaleh
źródło
0

ustaw Culture na angielski z pliku web.config

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

na przykład, jeśli ustawisz kulturę na arabską, tym razem będzie

22/09/2017 02:16:57 ص

i pojawia się błąd: Konwersja nie powiodła się podczas konwersji daty i / lub czasu z ciągu znaków podczas wstawiania daty i godziny

Yusuf
źródło
0

U mnie to zadziałało:

INSERT INTO [MyTable]
           ([ValidFrom]
           ,[ValidTo])
       VALUES
           ('2020-01-27 14:54:11.000'
           ,'2023-01-27 14:52:50.000')
Joel Wiklund
źródło