La conversion a échoué lors de la conversion de la date et / ou de l'heure à partir de la chaîne de caractères lors de l'insertion de la date / heure


164

J'essayais de créer une table comme suit,

create table table1(date1 datetime,date2 datetime);

J'ai d'abord essayé d'insérer des valeurs comme ci-dessous,

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

Il a donné une erreur en disant,

Impossible de convertir varchar en datetime

Ensuite, j'ai essayé le format ci-dessous comme l'un des articles suggérés par notre 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));

Mais j'obtiens toujours l'erreur en disant,

La conversion a échoué lors de la conversion de la date et / ou de l'heure à partir de la chaîne de caractères

Aucune suggestion?


2
@Damien_The_Unbeliever comme vous l'avez dit, j'ai déjà référencé ce post stackoverflow.com/questions/12957635/... avant de poser cette question. Ils nous ont demandé d'utiliser les valeurs 'insert table1 (date d'approbation) (convert (datetime, '18 -06-12 10:34:09 PM', 5)); ' mais ça ne marche pas
Mari

Réponses:


163

Il existe de nombreux formats pris en charge par SQL Server - consultez la documentation en ligne MSDN sur CAST et CONVERT . La plupart de ces formats dépendent des paramètres dont vous disposez - par conséquent, ces paramètres peuvent parfois fonctionner - et parfois non.

La façon de résoudre ce problème consiste à utiliser le format de date ISO-8601 (légèrement adapté) pris en charge par SQL Server - ce format fonctionne toujours - quels que soient vos paramètres de langue et de format de date SQL Server.

Le format ISO-8601 est pris en charge par SQL Server et se décline en deux versions:

  • YYYYMMDDpour juste des dates (aucune portion de temps); remarquez ici: pas de tirets! , c'est très important! YYYY-MM-DDn'est PAS indépendant des paramètres de format de date de votre serveur SQL et ne fonctionnera PAS dans toutes les situations!

ou:

  • YYYY-MM-DDTHH:MM:SSpour les dates et les heures - notez ici: ce format a des tirets (mais ils peuvent être omis), et un Tséparateur fixe entre la partie date et heure de votre fichier DATETIME.

Ceci est valable pour SQL Server 2000 et plus récent.

Donc, dans votre cas concret, utilisez ces chaînes:

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

et ça devrait aller (note: vous devez utiliser le format international de 24 heures plutôt que le format 12 heures AM / PM pour cela).

Alternativement : si vous êtes sur SQL Server 2008 ou plus récent, vous pouvez également utiliser le DATETIME2type de données (au lieu de plain DATETIME) et votre courant INSERTfonctionnera sans aucun problème! :-) DATETIME2est beaucoup mieux et beaucoup moins pointilleux sur les conversions - et ce sont les types de données date / heure recommandés pour SQL Server 2008 ou plus récent de toute façon.

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  

Ne me demandez pas pourquoi tout ce sujet est si délicat et quelque peu déroutant - c'est juste comme ça. Mais avec le YYYYMMDDformat, vous devriez être bien pour n'importe quelle version de SQL Server et pour tout paramètre de langue et de format de date dans votre SQL Server.


1
Pour rappel, la diffusion en tant que DATETIME2 fonctionne également avec 'YYYY-MM-DDTHH: MM: SSZ' (notez 'Z' - heure zoulou à la fin pour indiquer l'horodatage UTC). J'ai cette erreur en essayant d'insérer '2013-12-16T17: 21: 26Z' dans le champ datetime. Juste pour clarifier, ISO 8601 est partiellement pris en charge. Il ne prend pas en charge l'heure Zulu, bien qu'il soit mentionné dans la documentation. C'est probablement un cadre que je n'ai pas eu le temps de comprendre, mais au cas où quelqu'un aurait le même problème, gardez cela à l'esprit.
Michał

3
Je peux confirmer que le format de date 'YYYYMMDD' fonctionne bien, je l'ai essayé sur SQL Server 2014, comme moyen de spécifier une date littérale dans une clause WHERE. De nombreux chars à @marc_s
Giorgio Barchiesi

1
Le truc DATETIME2 a fonctionné pour moi. Dans mon cas, j'importais un script de base de données à partir d'un serveur SQL en anglais vers une version espagnole de celui-ci, donc à chaque fois la même erreur. J'ai simplement remplacé dans le script toutes les devises "as DATETIME" par "as DATETIME2" et le problème a été résolu.
Alejandro del Río

24

La conversion dans le serveur SQL échoue parfois pas à cause des formats de date ou d'heure utilisés, c'est simplement parce que vous essayez de stocker des données erronées qui ne sont pas acceptables pour le système.

Exemple:

Create Table MyTable (MyDate);

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

Le serveur SQL lancera l'erreur suivante:

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

La raison de cette erreur est simplement qu'il n'y a pas de date (29 février) dans l'année (2015).


2
"La raison de cette erreur est simplement qu'il n'y a pas de date (29 février) dans l'année (2015)" C'était exactement la raison pour laquelle j'obtenais cette erreur. Cette réponse prend en compte la cause la plus courante de cette erreur, ce que les autres réponses n'ont pas fait.
FirstFraktal

1
J'ai importé des données à partir d'une feuille Excel où les valeurs nulles avaient en fait "NULL" dans la cellule. Cela a été défini comme une chaîne "Null" dans la table de base de données, donc j'ai essayé de convertir la chaîne "Null" en datetime. Doit avoir vidé les cellules «NULL» dans Excel. Je suis un idiot: /
karol

17

Réponse simple - 5 est l'italien «yy» et 105 l'italien «yyyy». Par conséquent:

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

fonctionnera correctement, mais

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

donnera une erreur.

Également,

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

donnera une erreur, où comme

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

marchera.


8

Mettez simplement à jour le format de la date comme ci-dessous

yyyy-MM-dd hh:MM:ss

Cela résout le problème pour moi et cela fonctionne bien


2
Veuillez lire les autres réponses déjà fournies. Ce format ne fonctionne pour vous qu'en raison de vos DATEFORMATparamètres de session . Vérifiez cela en exécutant 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);. Cela fonctionnera de manière fiable si vous ajoutez un Tséparateur ( yyyy-MM-ddTHH:mm:ss).
Dan Guzman

1
Merci beaucoup oui vous avez raison cela résout mon problème et j'ai lu les autres réponses données ici
Pronab Roy

8

Dans la mesure du possible, il faut éviter les littéraux de date / heure spécifiques à la culture .

Il existe des formats sécurisés pour fournir une date / heure comme littéral:

Tous les exemples pour 2016-09-15 17:30:00

ODBC (mon préféré, car il est traité comme le type réel immédiatement)

  • {ts'2016-09-15 17:30:00'} - Timbre horaire
  • {d'2016-09-15'} --Date seulement
  • {t'17:30:00'} - Heure seulement

ISO8601 (le meilleur pour partout )

  • '2016-09-15T17:30:00'- soyez conscient du Tmilieu!

Non séparé (petit risque d'être mal interprété comme un nombre)

  • '20160915' --uniquement pour une date pure

Bon à garder à l'esprit: les dates non valides ont tendance à apparaître avec des erreurs étranges

  • Il n'y a pas de 31 juin ou 30 février ...

Une raison de plus pour d'étranges erreurs de conversion: l'ordre d'exécution!

SQL-Server est bien connu pour faire les choses dans un ordre d'exécution auquel on n'aurait pas pu s'attendre. Votre déclaration écrite semble que la conversion est effectuée avant qu'une action liée au type n'ait lieu, mais le moteur décide - pourquoi jamais - d'effectuer la conversion à une étape ultérieure.

Voici un excellent article expliquant cela avec des exemples: Rusano.com: "t-sql-functions-do-no-imply-a-certain-order-of-execution" et voici la question connexe .


3

le meilleur moyen est ce code

"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
Si vous utilisez des backticks plutôt que des espaces initiaux, vous obtiendrez un retour à la ligne.
Jesse W à Z - Abandonné le

2

Le format datetime qui s'exécute réellement sur le serveur SQL est

yyyy-mm-dd hh:MM:ss

1
Non, ce n'est pas vrai (à part le décalage de met M). Lisez le commentaire de Dan Guzman sur la réponse de Pronab Roy. Et lisez les autres réponses ici ...
Shnugo

2

Veuillez essayer ceci.

SQL Server attend des dates au format MM / JJ / AAAA, si l'anglais est défini comme langue par défaut.Voici l'enregistrement de la valeur du sélecteur de date dans la base de données sql2008.Mon type de champ est datetime dans la base de données.dpdob est mon nom de sélecteur de date.

           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

Maintenant, utilisez dob dans votre requête d'insertion.


1

Vous pouvez essayer ce code

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

1

J'ai eu ce problème en essayant de concaténer getdate()dans une chaîne que j'insérais dans un champ nvarchar.

J'ai fait du casting pour le contourner:

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

C'est un exemple purifié. La partie clé de cela est:

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

Jeter la date comme datetime2, puis nvarcharpour la concaténer.



0

définir Culture en anglais à partir du fichier web.config

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

par exemple, si vous définissez la culture sur arabe, le thime sera

22/09/2017 02:16:57 ص

et vous obtenez l'erreur: La conversion a échoué lors de la conversion de la date et / ou de l'heure à partir de la chaîne de caractères lors de l'insertion de datetime



0

Pour moi, cela a fonctionné:

INSERT INTO [MyTable]
           ([ValidFrom]
           ,[ValidTo])
       VALUES
           ('2020-01-27 14:54:11.000'
           ,'2023-01-27 14:52:50.000')
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.