SQL-从varchar数据类型到datetime数据类型的转换导致值超出范围


87

运行SQL到我的数据类型值从转换的时候,我一直得到以下错误varchardatetime

消息242,级别16,状态3,行1将varchar数据类型转换为datetime数据类型导致值超出范围。

我检查了数据,看不到任何奇怪的东西:进行了以下检查,所有结果均未返回

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

还有其他值得一看的东西,也许值得任何指针或帮助解决这个问题?似乎无法深究。


3
日期列的数据类型是什么?您能告诉我表模式,以及出现错误的语句吗?
Spikeh 2013年

3
您提供的六个SQL语句中的哪一个失败?
Mureinik 2013年

1
这六个语句均有效,并且验证数据没有问题。
user23495 2013年

3
您尚未检查无效日期,例如2013-10-31或2013-02-30。您可能遇到的错误可能是指这类有问题的日期
Dalen

2
嗨,达伦,我已经做了这张检查。数据的设置方式为2013年10月31日,2013年10月30日。它是英国格式。尝试更改列类型时会不会有任何影响,没想到会。
user23495 2013年

Answers:


84

我一周前也遇到过同样的问题。问题出在时区设置上。以其他格式指定,例如mm / dd / yyyy(通常有效)。

将日期指定为30/12/2013对我造成了错误。但是,将其指定为mm / dd / yyyy格式是可行的。

如果您需要转换输入,可以尝试查看该CONVERT方法。语法是

CONVERT(VARCHAR,@your_date_Value,103)

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

结束语103是日期时间格式。

请参阅此链接以获取转换格式和进一步的阅读。 https://www.w3schools.com/sql/func_sqlserver_convert.asp


1
感谢您的帮助。我尝试将其转换,但仍然没有任何运气。可能是由于table仍然是varchar还是其他原因导致此操作失败?
user23495 2013年

2
如果您发布示例数据(在表中),这将非常有帮助。在评论中,您说您想要yyyy-mm-dd格式。因此,请尝试此SELECT CONVERT(char(10), GetDate(),126)。只需将GETDATE()替换为必要的值即可。
Mahe 2013年

60

由于一个愚蠢的错误,我遇到了这个问题。确保日期实际存在!

例如:

不存在2015年9月31日。

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

因此,此消息失败:

Error converting data type varchar to datetime.

要解决此问题,请输入有效日期:

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

它执行得很好。


2
是的,我刚刚在要使用的数据库中找到了2015年2月29日的到期日期。我想知道它是怎么进入那里的。我想知道那里还有多少...
资源

4
刚使用cast(SUBSTRING([[MyDateField],1,2)作为整数)> 31)发现了12月60日的记录。谁输入这些东西,苏斯博士?
SteveCav 2015年

3
谢谢!这是我的问题。我的装置中有一些不良数据-01/01/1113,哈哈。
2016年

2
对我来说,格式化日期以构建SQL语句时,我输入了错误的格式字符串。我曾经用过Format(DateTime.Now, "yyyymmdd")应该用的时间Format(DateTime.Now, "yyyyMMdd")
杰伊·伊曼

1
美国日期约定!因为“ 2017年10月26日”(即“ 2017年10月26日”)是一个完全有效的日期

29

我最近有类似的问题。在应用程序和数据库服务器中都正确设置了区域设置。但是,SQL的执行导致

“将varchar数据类型转换为datetime数据类型导致值超出范围”。

问题是数据库用户的默认语言。

要在SSMS中检查或更改它,请转到安全性->登录名,然后右键单击运行查询的用户的用户名。选择属性->常规,并确保对话框底部的默认语言是您所期望的。

对所有运行查询的用户重复此操作。


1
这对我有帮助。只是一个小小的更正:server loginnot的默认语言db usertop-password.com/blog/...
巴兹Guvenkaya

1
由于它是在程序代码中设置的,并且我无权访问该代码,因此将其从更改为EnglishBritish English并且可以正常工作!
vaheeds,

1
我也一样,将英语改为英式英语-阿里,您是救生员!
大卫·乔治


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

5
请在您的答案中添加更多描述。这将有助于发问者从您的答案中掌握更多信息。
Pramod S. Nikam

2

我遇到了同样的问题,并确定出现此问题是因为SQL Server不会对以相同方式转换为整数的字符执行比较。在我的测试中,我发现转换后的字符的某些比较(例如感叹号)将返回类型转换错误,而转换后的字符的其他比较(例如空格)将被确定超出范围。

此示例代码测试了各种可能的情况,并使用嵌套的REPLACE语句提供了一种解决方案。REPLACE确定字符串中是否有任何非数字或斜杠的字符,如果存在,则字符串的长度将大于零,从而指示存在“坏”字符且日期无效。

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

输出:

--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

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

日期字符串为“ 19610010”(格式:YYYYMMDD)的行有问题,导致“将nvarchar数据类型转换为datetime数据类型导致值超出范围”错误。从[yourtable] WHERE ISDATE('yourdate')= 1中选择SELECT CONVERT(datetime,'yourdate')保存了一天:)
J Pollack

2

自动将sysdate插入列时,我也遇到了此问题。

我所做的是更改了系统日期格式,使其与SQL Server的日期格式匹配。例如,我的SQL格式为mm / dd / yyyy,而我的系统格式设置为dd / mm / yyyy。我将系统格式更改为mm / dd / yyyy,错误消失了

-kb


2

如您所知,这是英国格式的问题。您可以使用函数间接进行日期转换。

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

调用此功能

SELECT dbo.ChangeDateFormatFromUK([dates]) from table

通常将其转换为日期时间

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

就您而言,您可以

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

2

测试> 2079年。我发现用户在年份(10/12/2106)中输入了2106,而不是2016年的输入错误;因此,在2016年10月12日,我进行了测试,发现SQL Server最多接受2078年,如果年份为2079年或更高,则开始抛出该错误。关于滑动SQL Server的日期类型,我尚未做任何进一步的研究。


1

我只是简单地将要转换为新表(带有DateTime字段)的varchar字段转换为与DateTime兼容的布局,然后SQL会完成从varchar到DateTime的转换,而不会出现问题。

在下面(不是我用这些名称创建的表中!),如果要执行以下操作,只需将varchar字段设为类似DateTime即可:

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)  

1
Varchar Date Convert to Date and Change the Format

2016年11月12日12:00,2016年12月21日,2016年12月21日,此查询适用于以上格式更改为dd / MM / yyyy SELECT [Member_ID],[Name] , Convert(varchar(50),Convert(date,[DOB],103),103) as DOB ,[NICNO],[Relation] FROM [dbo].[tbl_FamilMember]


0

对我而言,发生此错误是因为我试图直接从C#代码使用内联查询将最小日期和时间存储在列中。

考虑到C#中的DateTime已使用该日期和时间初始化(如果未另外设置)的事实,则在代码中将date变量设置为01/01/0001 12:00:00 AM。并且MS-SQL 2008 datetime数据类型中允许的最小日期为1753-01-01 12:00:00 AM。

我从代码中更改了日期,并将其设置为01/01/1900,没有进一步报告错误。


0

我在具有mm而不是MM的日期上使用了ToString()。


0

只需确保您的日期兼容或可以在数据库管理器(例如SQL Server Management Studio)中正确运行即可。例如,DateTime.Now C#函数在SQL Server中无效,这意味着查询必须包含有效的函数,例如SQL Server的GETDATE()。

此更改对我而言非常有效。


0

造成此问题的原因略有不同,但以防万一有人需要它。我正在使用的代码正在使用:

java.text.DateFormat.getDateTimeInstance()

获取日期格式器。如该错误报告中所述,此调用返回的格式化模式已从Java 8更改为Java 9:https : //bugs.openjdk.java.net/browse/JDK-8152154显然,它为我返回的格式不适合用于数据库。解决方案是改为:

DateTimeFormatter.ISO_LOCAL_DATE_TIME
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.