65 votes

Convertir varchar en datetime dans SQL Server

Comment convertir une chaîne de format mmddyyyy en datetime dans SQL Server 2008 ?

Ma colonne cible est dans DateTime

J'ai essayé avec Convert et la plupart des Date mais je reçois un message d'erreur :

La conversion d'un type de données varchar en un type de données datetime a donné lieu à une valeur hors plage.

1 votes

Le tsql a-t-il une fonction str_to_date comme MySQL ? dev.mysql.com/doc/refman/5.1/fr/

2 votes

OP veut mmddyyyy ; select convert(datetime,'12312009') -->>>_Msg 242, Level 16, State 3, Line 1 La conversion d'un type de données char en un type de données datetime a donné lieu à une valeur datetime hors limites.

75voto

KM. Points 51800

L'OP veut mmddyy et un simple convertisseur ne fonctionnera pas pour cela :

select convert(datetime,'12312009')

Msg 242, Level 16, State 3, Line 1 
The conversion of a char data type to a datetime data type resulted in 
an out-of-range datetime value

alors essayez ceci :

DECLARE @Date char(8)
set @Date='12312009'
SELECT CONVERT(datetime,RIGHT(@Date,4)+LEFT(@Date,2)+SUBSTRING(@Date,3,2))

SORTIE :

-----------------------
2009-12-31 00:00:00.000

(1 row(s) affected)

2 votes

+1, mais ne serait-il pas agréable de ne pas avoir à épisser les chaînes de caractères ? techonthenet.com/oracle/functions/to_date.php

11 votes

@dwerner, si vous ne voulez pas avoir à faire ce genre de choses, ne stockez pas dans un type de données incorrect.

2 votes

Corrigez-moi si je me trompe, mais c'était le problème proposé par la question. Ma suggestion est d'utiliser une fonction adaptée au but recherché.

7voto

nick Points 51

Le serveur SQL peut implicitement convertir des chaînes sous la forme 'YYYYMMDD' en une date - toutes les autres chaînes doivent être explicitement converties. Voici deux blocs de code rapides qui effectueront la conversion à partir de la forme dont vous parlez :

La version 1 utilise des variables unitaires :

BEGIN 
DECLARE @input VARCHAR(8), @mon CHAR(2), 
@day char(2), @year char(4), @output DATETIME

SET @input = '10022009'   --today's date

SELECT @mon = LEFT(@input, 2), @day = SUBSTRING(@input, 3,2), @year = RIGHT(@input,4)

SELECT @output = @year+@mon+@day 
SELECT @output 
END

La version 2 n'utilise pas de variables unitaires :

BEGIN 
DECLARE @input CHAR(8), @output DATETIME
SET @input = '10022009' --today's date 

SELECT @output = RIGHT(@input,4) + SUBSTRING(@input, 3,2) + LEFT(@input, 2)

SELECT @output
END

Les deux cas reposent sur la capacité du serveur SQL à effectuer cette conversion implicite.

5voto

HLGEM Points 54641

Il est probable que vos données sont mauvaises et ne peuvent pas être converties. Les dates ne doivent jamais être stockées dans un fichier varchar, car il autorise des dates telles que ASAP ou 02/30/2009. Utilisez la fonction isdate() sur vos données pour trouver les enregistrements qui ne peuvent pas être convertis.

OK, j'ai testé avec des données connues et bonnes et j'ai toujours le message. Vous devez convertir dans un format différent car il ne sait pas si 12302009 est mmddyyyy ou ddmmyyyy. Le format yyyymmdd n'est pas ambigu et le serveur SQL le convertira correctement.

J'ai réussi à faire fonctionner ça :

cast( right(@date,4) + left(@date,4) as datetime)

Cependant, vous obtiendrez toujours un message d'erreur si vous en avez qui sont dans un format non standard comme '112009' ou une valeur de texte ou une vraie date hors de la plage.

0 votes

Après avoir effectué quelques tests sur un million de chaînes de dates aléatoires au format mmddyyyy comme celles du PO, il s'avère que cette méthode est à la fois la plus rapide à exécuter et la plus facile à coder. Il existe d'autres méthodes qui rivalisent en termes de performances mais, parmi tous les codes qui fonctionnent réellement comme le demande l'OP dans ce fil de discussion, celui-ci l'emporte à chaque fois. L'écart n'est pas de plus de 25 ms sur un million de lignes mais, compte tenu de la facilité de codage et de la charge des autres méthodes que j'ai testées, celle-ci l'emporte.

4voto

Andrew Points 14278

Convertir serait la réponse normale, mais le format n'est pas un format reconnu par le convertisseur, mm/dd/yyyy pourrait être converti en utilisant convert(datetime,yourdatestring,101) mais vous n'avez pas ce format et cela échoue.

Le problème est que le format n'étant pas standard, vous devrez le manipuler en fonction d'une norme que le convertisseur peut comprendre parmi celles disponibles.

bricolé, si vous pouvez garantir le format.

declare @date char(8)
set @date = '12312009'
select convert(datetime, substring(@date,5,4) + substring(@date,1,2) + substring(@date,3,2),112)

1voto

Charles Bretana Points 59899

Utilisez la fonction Convert ou Cast it...

Convertir et couler

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X