Při převodu data a/nebo času ze znakového řetězce při vkládání datetime se převod nezdařil

Snažil jsem se vytvořit následující tabulku,

create table table1(date1 datetime,date2 datetime);

Nejdříve jsem zkoušel vkládat hodnoty, jak je uvedeno níže,

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

Vyskytla se chyba s hláškou,

Nelze převést varchar na datetime

Pak jsem zkusil níže uvedený formát, jak navrhuje jeden z příspěvků našeho 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 stále dostávám chybu, která říká,

Při převodu data a/nebo času ze znakového řetězce se konverze nezdařila

Nějaké návrhy?

Řešení

SQL Server podporuje mnoho formátů - viz MSDN Books Online on CAST and CONVERT. Většina těchto formátů je závislá na tom, jaká máte nastavení - proto tato nastavení mohou někdy fungovat - a někdy ne.

Řešením je použití (mírně upraveného) formátu data ISO-8601, který je podporován serverem SQL Server - tento formát funguje vždy - bez ohledu na nastavení jazyka a formátu data serveru SQL Server.

Formát ISO-8601 podporovaný serverem SQL Server se dodává ve dvou variantách:

  • YYYYMMDD pro pouhá data (bez časové části); pozn. překl: žádné pomlčky!, to je velmi důležité! YYYY-MM-DD není nezávislý na nastavení formátu data v SQL Serveru a nefunguje ve všech situacích!

nebo:

  • Tento formát pomlčky (ale mohou být vynechány) a pevný znak T jako oddělovač mezi částí data a času vašeho DATETIME.

To platí pro SQL Server 2000 a novější.

Takže ve vašem konkrétním případě - použijte tyto řetězce:

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

a mělo by to být v pořádku (poznámka: je třeba použít mezinárodní formát 24 hodin, nikoli 12hodinový formát AM/PM).

Alternativa: pokud používáte SQL Server 2008 nebo novější, můžete také použít datový typ DATETIME2 (místo prostého DATETIME) a váš současný INSERT bude prostě fungovat bez problémů! :-) DATETIME2 je mnohem lepší a mnohem méně náročný na konverze - a navíc je to doporučený datový typ pro SQL Server 2008 a novější.

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  

Neptejte se mě, proč je celé toto téma tak ošemetné a poněkud matoucí - tak to prostě je. Ale s formátem RRRRMMDD byste si měli poradit pro jakoukoli verzi SQL Serveru a pro jakýkoli jazyk a nastavení formátu data ve vašem SQL Serveru.

Komentáře (3)

Konverze v SQL serveru někdy selže ne kvůli použitým formátům data nebo času, ale pouze proto, že se snažíte uložit nesprávná data, která nejsou pro systém přijatelná.

Příklad:

Vytvořit tabulku MyTable (MyDate);`

Vložit do tabulky MyTable(MyDate) hodnoty ('2015-02-29');

SQL server vyhodí následující chybu:

Při převodu data a/nebo času ze znakového řetězce se konverze nezdařila.

Důvodem této chyby je, že v roce (2015) prostě neexistuje žádné takové datum (29. února).

Komentáře (2)

Jednoduchá odpověď - 5 je italsky "yy" a 105 je italsky "yyyy". Proto:

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

bude fungovat správně, ale

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

se zobrazí chyba.

Podobně,

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

způsobí chybu, kdežto

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

bude fungovat.

Komentáře (0)