SQL - La conversion d'un type de données varchar en un type de données datetime a abouti à une valeur hors plage

87

J'ai reçu l'erreur suivante lors de l'exécution d'un SQL pour convertir la valeur de mon type de données de varcharà datetime.

Msg 242, niveau 16, état 3, ligne 1 La conversion d'un type de données varchar en un type de données datetime a abouti à une valeur hors plage.

J'ai vérifié les données et je ne vois rien d'étrange: j'ai effectué les vérifications suivantes et je n'ai renvoyé aucun résultat

SELECT [Date] from table where [DATe] is null
SELECT [Date] from table where [DATe] = ''
SELECT [Date] from table where LEN([date])> 10
SELECT [Date] from table where LEN([date])< 10
SELECT top 100 [Date] , SUBSTRING([date],4,2) from [table where convert(int, SUBSTRING([date],4,2)) < 1 or convert(int, SUBSTRING([date],4,2)) > 12
SELECT top 100 [Date] , SUBSTRING([date],1,2) from table where convert(int, SUBSTRING([date],4,2)) < 1 or convert(int, SUBSTRING([date],4,2)) > 31

Y a-t-il autre chose qui vaut la peine d'être examiné et qui mérite peut-être des conseils ou une aide sur ce problème? Je n'arrive pas à comprendre.

user23495
la source
3
Quel est le type de données de la colonne de date? Pouvez-vous me montrer le schéma de la table et la déclaration selon laquelle l'erreur se produit s'il vous plaît?
Spikeh
3
laquelle des six instructions SQL que vous avez fournies échoue?
Mureinik
1
Les six déclarations fonctionnent toutes et ne vérifient aucun problème avec les données.
user23495
3
vous n'avez pas vérifié les dates non valides, par exemple 2013-10-31 ou 2013-02-30. Probablement, l'erreur à laquelle vous êtes confronté fait référence à ce genre de dates problématiques
Dalen
2
Salut Dalen, j'ai fait cette vérification. La configuration des données est le 31/10/2013, 30/10/2013. Il est au format britannique. Cela aura-t-il un impact lors de la tentative de modification d'un type de colonne, je ne pensais pas que ce serait le cas.
user23495

Réponses:

84

J'ai été confronté au même problème il y a une semaine. Le problème vient du réglage du fuseau horaire. Spécifiez dans d'autres formats comme mm / jj / aaaa (fonctionne généralement).

Spécifier la date au 30/12/2013 a entraîné l'erreur pour moi. Cependant, le spécifier au format mm / jj / aaaa fonctionnait.

Si vous avez besoin de convertir votre entrée, vous pouvez essayer de rechercher la CONVERTméthode. La syntaxe est

CONVERT(VARCHAR,@your_date_Value,103)

CONVERT(VARCHAR, '12/30/2013', 103)

La finition 103 est le format datetime.

Reportez-vous à ce lien pour connaître les formats de conversion et lire davantage https://www.w3schools.com/sql/func_sqlserver_convert.asp

Mahé
la source
1
Merci pour l'aide-partenaire. J'ai essayé de le convertir mais je n'ai toujours pas eu de chance. Cela pourrait-il être dû au fait que la table est encore un varchar ou à toute autre chose qui peut provoquer l'échec de cette opération?
user23495
2
Il serait très utile de publier vos exemples de données (qui se trouvent dans le tableau). En commentaire, vous avez dit que vous le vouliez au format aaaa-mm-jj. Alors, essayez ceci SELECT CONVERT(char(10), GetDate(),126). Remplacez simplement GETDATE () par la valeur nécessaire.
Mahe
60

Je suis tombé sur ce problème en raison d'une erreur stupide. Assurez-vous que la date existe réellement!

Par exemple:

Le 31 septembre 2015 n'existe pas.

EXEC dbo.SearchByDateRange @Start = '20150901' , @End = '20150931'

Donc, cela échoue avec le message:

Error converting data type varchar to datetime.

Pour résoudre ce problème, saisissez une date valide:

EXEC dbo.SearchByDateRange @Start = '20150901' , @End = '20150930'

Et il s'exécute très bien.

Monsieur C
la source
2
Ouais, je viens de trouver une date d'expiration du 29 février 2015 dans la base de données avec laquelle je dois travailler. Je me demande comment cela est entré là-dedans. Je me demande combien il y en a d'autres là-dedans ...
Ressource
4
Juste utilisé cast (SUBSTRING ([MyDateField], 1,2) as integer)> 31 et trouvé un enregistrement avec le 60 décembre. Qui entre dans ce truc, Dr Suess?
SteveCav
3
Merci! C'était mon problème. J'avais de mauvaises données dans mon set - 01/01/1113, haha.
Sev09
2
Pour moi, j'avais mis la mauvaise chaîne de format lors du formatage de la date pour construire l'instruction SQL. J'avais utilisé Format(DateTime.Now, "yyyymmdd")quand ça aurait dû êtreFormat(DateTime.Now, "yyyyMMdd")
Jay Imerman
1
Conventions de date Argh américaines! M'avait été perplexe pendant un certain temps, puisque "26 octobre 2017" ie., '26 -10-2017 'est une date parfaitement valable :)
Antimoine
29

J'ai eu un problème similaire récemment. Les paramètres régionaux ont été correctement configurés à la fois dans l'application et le serveur de base de données. Cependant, l'exécution de SQL a entraîné

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

Le problème était la langue par défaut de l'utilisateur de la base de données.

Pour le vérifier ou le modifier dans SSMS, accédez à Sécurité -> Connexions et cliquez avec le bouton droit sur le nom d'utilisateur de l'utilisateur qui exécute les requêtes. Sélectionnez propriétés -> général et assurez-vous que la langue par défaut au bas de la boîte de dialogue correspond à ce que vous attendez.

Répétez cette opération pour tous les utilisateurs qui exécutent des requêtes.

Ali
la source
1
Cela m'a aidé. Juste une petite correction: la langue par défaut du server loginnon db user. top-password.com/blog/…
Baz Guvenkaya
1
Comme il est défini dans le code du programme et que je n'ai pas accès au code, je l'ai changé de Englishen British Englishet cela a fonctionné!
vaheeds
1
Pareil pour moi ahd de changer l'anglais en anglais britannique - Ali, vous sauvez la vie!
david-giorgi
10

Vous pouvez utiliser

Set dateformat <date-format> ;

dans votre fonction sp ou procédure stockée pour faire avancer les choses.

Sachin Mishra
la source
1
Cela a résolu mon problème. Ce que je ne comprends pas, c'est pourquoi cela commence à se produire soudainement :(
VictorEspina
4
Create procedure [dbo].[a]

@examdate varchar(10) ,
@examdate1 varchar(10)
AS
Select tbl.sno,mark,subject1,
Convert(varchar(10),examdate,103) from tbl
where 
(Convert(datetime,examdate,103)  >= Convert(datetime,@examdate,103) 
and (Convert(datetime,examdate,103) <=  Convert(datetime,@examdate1,103)))
sonu yadav
la source
5
Veuillez ajouter plus de description à votre réponse. Cela aidera le questionneur à mieux saisir votre réponse.
Pramod S. Nikam
2

J'ai eu le même problème et j'ai déterminé que ce problème survient parce que SQL Server n'effectue pas de comparaisons sur les caractères convertis en nombres entiers de la même manière. Dans mon test, j'ai constaté que certaines comparaisons de caractères convertis, tels que le point d'exclamation, renverront des erreurs de conversion de type, tandis que d'autres comparaisons de caractères convertis, tels que l'espace, seront jugées hors limites.

Cet exemple de code teste les différents scénarios possibles et présente une solution à l'aide d'instructions REPLACE imbriquées. Le REMPLACER détermine s'il y a des caractères dans la chaîne qui ne sont pas des chiffres ou la barre oblique, et, s'il en existe, la longueur de la chaîne sera supérieure à zéro, indiquant ainsi qu'il y a des `` mauvais '' caractères et que la date n'est pas valide .

DECLARE @str varchar(10)
SET @str = '12/10/2012'
IF convert(int, substring(@str,4,2)) <= 31 AND convert(int, substring(@str,4,2)) >= 1
    PRINT @str+': Passed Test'
    ELSE PRINT @str+': Failed Test'
GO

DECLARE @str varchar(10)
SET @str = '12/10/2012' 
PRINT 'Number of characters in ' + @str + ' that are not numerals or a slash (0 means the date is valid; all values greater than 0 indicate a problem): ' + convert(varchar(5),len(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(@str,'0',''),'1',''),'2',''),'3',''),'4',''),'5',''),'6',''),'7',''), '8',''),'9',''),'/',''),' ','+'))) --replace space with a + to avoid empty string
PRINT ''
GO

DECLARE @str varchar(10)
SET @str = '12/!0/2012'
    IF convert(int, substring(@str,4,2)) <= 31 AND convert(int, substring(@str,4,2)) >= 1
        PRINT @str+': Passed Test'
        ELSE PRINT @str+': Failed Test'
GO

DECLARE @str varchar(10)
SET @str = '12/!0/2012' 
PRINT 'Number of characters in ' + @str + ' that are not numerals or a slash (0 means the date is valid; all values greater than 0 indicate a problem): ' + convert(varchar(5),len(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(@str,'0',''),'1',''),'2',''),'3',''),'4',''),'5',''),'6',''),'7',''), '8',''),'9',''),'/',''),' ','+'))) --replace space with a + to avoid empty string
PRINT ''
GO

DECLARE @str varchar(10)
SET @str = '12/  /2012'
IF convert(int, substring(@str,4,2)) <= 31 AND convert(int, substring(@str,4,2)) >= 1
    PRINT @str+': Passed Test'
    ELSE PRINT @str+': Failed Test'
GO

DECLARE @str varchar(10)
SET @str = '12/  /2012' 
PRINT 'Number of characters in ' + @str + ' that are not numerals or a slash (0 means the date is valid; all values greater than 0 indicate a problem): ' + convert(varchar(5),len(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(@str,'0',''),'1',''),'2',''),'3',''),'4',''),'5',''),'6',''),'7',''), '8',''),'9',''),'/',''),' ','+'))) --replace space with a + to avoid empty string

Production:

--Output
--12/10/2012: Passed Test
--Number of characters in 12/10/2012 that are not numerals or a slash (0 means the date is valid; all values greater than 0 indicate a problem): 0

--Msg 245, Level 16, State 1, Line 4
--Conversion failed when converting the varchar value '!0' to data type int.
--Number of characters in 12/!0/2012 that are not numerals or a slash (0 means the date is valid; all values greater than 0 indicate a problem): 1

--12/  /2012: Failed Test
--Number of characters in 12/  /2012 that are not numerals or a slash (0 means the date is valid; all values greater than 0 indicate a problem): 2
RSax
la source
2
+ this happens because sql sometimes doesn't recognize dd/mm/yyyy format
+ so we should always check if the input string is a valid date or not and the accordingly convert it to mm/dd/yyyy and so , i have shown below how it can be done, i have created a function to rearrange in mm/dd/yyyy from dd/mm/yyyy

select case when isdate('yourdate')=1 then CAST('yourdate' AS datetime) 
  else (select * from dbo.fn_convertdate(yourdate))

Create function dbo.fn_convertdate( @Stringdate nvarchar(29))
RETURNS @output TABLE(splitdata NVARCHAR(MAX) 
)
Begin
Declare @table table(id int identity(1,1), data varchar(255))
Declare @firstpart nvarchar(255)
Declare @tableout table(id int identity(1,1), data varchar(255))

Declare @Secondpart nvarchar(255)
Declare @Thirdpart nvarchar(255)

declare @date datetime

insert into @table
select * from dbo.fnSplitString(@Stringdate,'/')
select @firstpart=data from @table where id=2
select @Secondpart=data from @table where id=1
select @Thirdpart=data from @table where id=3
set @date=@firstpart+'/'+@Secondpart+'/'+@Thirdpart
insert into @output(splitdata) values(
@date)


return
End
shashank m
la source
Il y avait une ligne problématique avec la chaîne de date «19610010» (format: AAAAMMJJ) qui a provoqué une erreur «La conversion d'un type de données nvarchar en un type de données datetime a entraîné une valeur hors limites». SELECT CONVERT (datetime, 'yourdate') FROM [yourtable] WHERE ISDATE ('yourdate') = 1 a sauvé la journée :)
J Pollack
2

J'ai également rencontré ce problème lors de l'insertion automatique d'un sysdate dans une colonne.

J'ai changé le format de date de mon système pour qu'il corresponde au format de date du serveur SQL. par exemple, mon format SQL était mm / jj / aaaa et mon format système était défini sur jj / mm / aaaa. J'ai changé le format de mon système en mm / jj / aaaa et l'erreur a disparu

-kb

user5714464
la source
2

Comme vous le savez, il s'agit d'un problème de format britannique. Vous pouvez effectuer une conversion de date indirectement en utilisant la fonction.

CREATE FUNCTION  ChangeDateFormatFromUK
( 
   @DateColumn varchar(10)
)

RETURNS VARCHAR(10)
AS 
 BEGIN
    DECLARE @Year varchar(4), @Month varchar(2), @Day varchar(2), @Result varchar(10)
    SET @Year = (SELECT substring(@DateColumn,7,10))
    SET @Month = (SELECT substring(@DateColumn,4,5)) 
    SET @Day = (SELECT substring(@DateColumn,1,2))
   SET @Result  = @Year  + '/' @Month + '/' +  @Day

 RETURN @Result
END

Pour appeler cette fonction

SELECT dbo.ChangeDateFormatFromUK([dates]) from table

Convertissez-le normalement en datetime

SELECT CONVERT(DATETIME,dbo.ChangeDateFormatFromUK([dates])) from table

Dans votre cas, vous pouvez faire

SELECT [dates] from table where CONVERT(DATETIME,dbo.ChangeDateFormatFromUK([dates])) > GetDate()   -- or any date
Sumit
la source
2

Test pour l'année> 2079. J'ai trouvé qu'un utilisateur a tapé 2106 au lieu de 2016 dans l'année (10/12/2106) et boom; Ainsi, le 12/10/2016, j'ai testé et trouvé SQL Server accepté jusqu'en 2078, j'ai commencé à lancer cette erreur si l'année est 2079 ou plus. Je n'ai pas fait de recherche supplémentaire sur le type de glissement de date de SQL Server.

Gordon
la source
1

J'ai simplement converti le champ varchar que je voulais convertir en une nouvelle table (avec un champ DateTime) en une mise en page compatible DateTime, puis SQL effectuera la conversion de varchar à DateTime sans problème.

Dans ce qui suit (pas ma table créée avec ces noms!) Je fais simplement du champ varchar un sosie de DateTime si vous voulez:

update report1455062507424 
set [Move Time] = substring([Move Time], 7, 4) + '-'+ substring([Move Time], 4, 2) + '-'+ substring([Move Time], 1, 2) + ' ' + 
    substring([Move Time], 12, 5)  
André
la source
1
Varchar Date Convert to Date and Change the Format

12 novembre 2016 12:00, 21/12/2016, 21-12-2016 cette requête fonctionne pour ci-dessus pour passer à ce format jj / MM / aaaa SELECT [Member_ID],[Name] , Convert(varchar(50),Convert(date,[DOB],103),103) as DOB ,[NICNO],[Relation] FROM [dbo].[tbl_FamilMember]

Khalid
la source
0

Cette erreur s'est produite pour moi parce que j'essayais de stocker la date et l'heure minimales dans une colonne à l'aide de requêtes en ligne directement à partir du code C #.

La variable de date a été définie sur 01/01/0001 12:00:00 AM dans le code étant donné que DateTime en C # est initialisé avec cette date et heure s'il n'est pas défini autrement. Et la date la plus petite possible autorisée dans le type de données datetime MS-SQL 2008 est 1753-01-01 12:00:00 AM.

J'ai changé la date du code et l'ai réglée sur 01/01/1900 et aucune erreur n'a été signalée.

Talha Imam
la source
0

J'ai utilisé ToString () à une date avec mm au lieu de MM.

L0uis
la source
0

Assurez-vous simplement que vos dates sont compatibles ou peuvent être exécutées correctement dans votre gestionnaire de base de données (par exemple SQL Server Management Studio). Par exemple, la fonction DateTime.Now C # n'est pas valide dans SQL Server, ce qui signifie que votre requête doit inclure des fonctions valides telles que GETDATE () pour SQL Server.

Ce changement a parfaitement fonctionné pour moi.

tonderaimuchada
la source
0

Cause légèrement inhabituelle pour ce problème, mais juste au cas où quelqu'un en aurait besoin. Le code sur lequel je travaillais utilisait:

java.text.DateFormat.getDateTimeInstance()

pour obtenir un formateur de date. Le modèle de formatage renvoyé par cet appel est passé de Java 8 à Java 9 comme décrit dans ce rapport de bogue: https://bugs.openjdk.java.net/browse/JDK-8152154 apparemment, le formatage qu'il renvoyait pour moi ne convenait pas pour la base de données. La solution était à la place:

DateTimeFormatter.ISO_LOCAL_DATE_TIME
wobblycogs
la source