Konwersja nie powiodła się podczas konwersji daty i/lub czasu z łańcucha znaków podczas wstawiania datetime

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

To dało 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 wciąż dostaję błąd mówiący,

Konwersja nie powiodła się podczas konwersji daty i/lub czasu z łańcucha znaków.

Jakieś sugestie?

Rozwiązanie

Istnieje wiele formatów obsługiwanych przez SQL Server - zobacz MSDN Books Online on CAST and CONVERT. Większość z tych formatów jest zależna od ustawień, które posiadasz - dlatego te ustawienia mogą działać czasami, a czasami nie.

Sposobem na rozwiązanie tego problemu jest użycie (lekko zaadaptowanego) ISO-8601 formatu daty, 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 obsługiwany przez SQL Server występuje w dwóch odmianach:

  • YYYYMMDD dla samych dat (bez części czasowej); zauważ tutaj: brak myślników!, to'jest bardzo ważne! YYYY-MM-DD nie jest niezależne od ustawień formatu daty w SQL Server i nie będzie działać we wszystkich sytuacjach!

lub:

  • YYYY-MM-DDTHH:MM:SS dla dat i czasów - uwaga tutaj: ten format posiada myślniki (ale można je pominąć), oraz stałe T jako delimiter pomiędzy datą i częścią czasową twojego DATETIME.

Jest to ważne dla SQL Server 2000 i nowszych.

Więc w twoim 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: musisz użyć międzynarodowego 24-godzinnego formatu zamiast 12-godzinnego formatu AM/PM do tego).

Alternatywnie: jeśli jesteś na SQL Server 2008 lub nowszym, możesz również użyć typu danych DATETIME2 (zamiast zwykłego DATETIME) i twój obecny INSERT będzie działał bez żadnych problemów! :-) DATETIME2 jest o wiele lepszy i o wiele mniej wybredny przy konwersji - i jest to zalecany typ danych daty/czasu dla SQL Server 2008 lub nowszych.

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 pytaj mnie dlaczego ten cały temat jest tak skomplikowany i nieco zagmatwany - tak po prostu jest. Ale z formatem YYYYMMDD, powinieneś być w porządku dla każdej wersji SQL Server i dla każdego języka i ustawienia formatu daty w twoim SQL Server.

Komentarze (3)

Konwersja w serwerze SQL czasami nie udaje się z powodu formatów daty lub czasu, to jest po prostu dlatego, że próbujesz przechowywać 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 wyrzuci 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 (Feb-29) w roku (2015).

Komentarze (2)

Prosta odpowiedź - 5 to włoskie "yy", a 105 to włoskie "yyyy". Zatem:

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)

spowoduje błąd.

Podobnie,

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

da błąd, gdzie jako

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

będzie działać.

Komentarze (0)