【问题标题】:SQL - The conversion of a varchar data type to a datetime data type resulted in an out-of-range valueSQL - 将 varchar 数据类型转换为 datetime 数据类型导致值超出范围
【发布时间】:2014-01-17 06:26:02
【问题描述】:

在运行 SQL 以将我的数据类型值从​​ varchar 转换为 datetime 时出现以下错误。

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

还有什么值得一看的,也许值得任何指点或帮助解决这个问题?似乎无法深入了解它。

【问题讨论】:

  • 日期列的数据类型是什么?你能告诉我表模式,以及错误发生的语句吗?
  • 您提供的六条 SQL 语句中哪一条失败了?
  • 这六个语句都有效并且验证数据没有问题。
  • 您尚未检查无效日期,例如2013 年 10 月 31 日或 2013 年 2 月 30 日。可能,您面临的错误是指那种有问题的日期
  • 嗨,Dalen,我已经完成了这项检查。数据的设置方式是 31/10/2013、30/10/2013。它是英国格式。这在尝试更改列类型时会不会有任何影响,没想到会。

标签: sql-server tsql datetime


【解决方案1】:

一周前我遇到了同样的问题。 问题在于时区设置。以其他格式指定,例如 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

【讨论】:

  • 感谢朋友的帮助。我试图转换它,但仍然没有任何运气。可能是由于 table 仍然是 varchar 还是其他任何可能导致失败的原因?
  • 如果您发布您的示例数据(在表格中)会很有帮助。在评论中你说你想要 yyyy-mm-dd 格式。所以,试试这个SELECT CONVERT(char(10), GetDate(),126)。只需将 GETDATE() 替换为必要的值即可。
【解决方案2】:

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

例如:

2015 年 9 月 31 日不存在。

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

所以这会失败并显示消息:

Error converting data type varchar to datetime.

要修复它,请输入有效日期:

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

它执行得很好。

【讨论】:

  • 是的,我刚刚在我必须使用的数据库中找到了 2015 年 2 月 29 日的到期日期。我想知道它是怎么进来的。我想知道那里还有多少...
  • 刚用了 cast(SUBSTRING([MyDateField],1,2) as integer) > 31 发现了12月60日的记录。谁进入了这些东西,Suess 博士?
  • 谢谢!这是我的问题。我的数据集中有一些不好的数据 - 1113 年 1 月 1 日,哈哈。
  • 对我来说,在格式化日期以构建 SQL 语句时,我输入了错误的格式字符串。我使用了Format(DateTime.Now, "yyyymmdd"),而它应该是Format(DateTime.Now, "yyyyMMdd")
  • Argh 美国日期约定!让我难过一阵子,因为“2017 年 10 月 26 日”,即“2017 年 10 月 26 日”是一个完全有效的日期:)
【解决方案3】:

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

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

问题是 db 用户的默认语言。

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

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

【讨论】:

  • 这对我有帮助。只是一个小的更正:server login 的默认语言不是db usertop-password.com/blog/…
  • 由于它设置在程序代码中并且我无法访问代码,因此我将其从 English 更改为 British English 并且有效!
  • 我也一样啊,把英语改成英式英语 - 阿里,你是救生员!
  • 我就是这么做的,我把英语改成了英式英语,效果很好。
【解决方案4】:

你可以利用

Set dateformat <date-format> ;

在你的 sp 函数或存储过程中完成任务。

【讨论】:

【解决方案5】:
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)))

【讨论】:

  • 请在您的答案中添加更多描述。这将有助于提问者从您的答案中获得更多信息。
【解决方案6】:

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

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

【讨论】:

    【解决方案7】:

    我遇到了同样的问题,并确定出现此问题是因为 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
    

    【讨论】:

      【解决方案8】:
      + 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 数据类型转换为日期时间数据类型导致值超出范围”错误。 SELECT CONVERT(datetime, 'yourdate') FROM [yourtable] WHERE ISDATE('yourdate')=1 保存了这一天:)
      【解决方案9】:

      我在将 sysdate 自动插入列时也遇到了这个问题。

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

      -kb

      【讨论】:

        【解决方案10】:

        测试年份 > 2079。 我发现用户在当年(2106 年 10 月 12 日)输入了 2106 而不是 2016 并且繁荣;所以在 2016 年 10 月 12 日,我测试并发现 SQL Server 接受到 2078,如果年份是 2079 或更高,则开始抛出该错误。我还没有进一步研究 SQL Server 的日期滑动类型。

        【讨论】:

          【解决方案11】:

          我只是先将想要转换为新表(带有 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)  
          

          【讨论】:

            【解决方案12】:
            Varchar Date Convert to Date and Change the Format
            

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

            【讨论】:

              【解决方案13】:

              在顶部添加:

              SET DATEFORMAT ymd; 
              

              或您在查询中使用的任何格式

              【讨论】:

              • 这解决了我的问题。不知何故,我的 SQL Server 无法从字符串格式 (dd/MM/yyyy) 解析正确格式化的欧盟日期,谢谢斯蒂芬。投票赞成:-)
              • 就我而言,我使用了 SET DATEFORMAT dmy;问题解决了。
              【解决方案14】:

              这个错误发生在我身上,因为我试图使用直接来自 C# 代码的内联查询将最小日期和时间存储在列中。

              日期变量在代码中设置为 01/01/0001 12:00:00 AM,因为 C# 中的 DateTime 是使用此日期和时间初始化的,如果没有设置其他方式。 MS-SQL 2008 日期时间数据类型中允许的最短日期是 1753-01-01 12:00:00 AM。

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

              【讨论】:

                【解决方案15】:

                我在日期使用 ToString(),而不是 MM。

                【讨论】:

                  【解决方案16】:

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

                  这个改变对我来说非常有效。

                  【讨论】:

                    【解决方案17】:

                    这个问题的原因有点不寻常,但以防万一有人需要。我正在处理的代码正在使用:

                    java.text.DateFormat.getDateTimeInstance()
                    

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

                    DateTimeFormatter.ISO_LOCAL_DATE_TIME
                    

                    【讨论】:

                      【解决方案18】:

                      我遇到了类似的问题。我不认为很多人会面临我所面临的情况。尽管如此,我还是想分享我的经验。我在测试环境中工作,并且有设置为最小日期时间值 0001/01/01 的日期时间数据。该值小于 smalldatetime 数据类型的最小可能数据。因此,请务必检查数据类型的 Min Max 值。 smalldatetime可以参考这个页面:https://docs.microsoft.com/en-us/sql/t-sql/data-types/smalldatetime-transact-sql?view=sql-server-ver15

                      【讨论】:

                        【解决方案19】:

                        我也遇到过类似的问题,经过调查发现,数据库中有很旧的日期。

                        所以我发现从日期到日期时间的转换仅适用于 1753-01-01(包括在内)之后的日期。

                        select CONVERT(Datetime, '1753-01-01', 103) as RESULT
                        --1753-01-01 00:00:00.000
                        
                        select CONVERT(Datetime, '1752-12-31', 103) as RESULT
                        --The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
                        

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 2011-11-12
                          • 2016-02-08
                          • 1970-01-01
                          • 2014-07-06
                          相关资源
                          最近更新 更多