有人可以解释一下我,为什么会出现错误
将varchar数据类型转换为datetime数据类型 值超出范围。
当我在SQL Server 2017上执行以下代码时。我仅在.999毫秒内收到错误
APP_PLATFORM := android-9
APP_STL := gnustl_static
APP_ABI := all
#APP_OPTIM := debug
APP_OPTIM := release
ifeq ($(APP_OPTIM),debug)
APP_CPPFLAGS := -O0 -g $(APP_CPPFLAGS)
else
APP_CPPFLAGS := -O2 -DNDEBUG -g $(APP_CPPFLAGS)
endif
结果:
将varchar数据类型转换为datetime数据类型 值超出范围。
然后我尝试:
SELECT CAST('9999-12-31 23:59:59.999' AS DATETIME)
结果:9999-12-31 23:59:59.997
然后我尝试:
SELECT CAST('9999-12-31 23:59:59.998' AS DATETIME)
结果:9999-12-31 23:59:59.997
答案 0 :(得分:3)
根据文档,日期时间范围在1753年1月1日到9999年12月31日之间。同样,根据文档,时间范围在00到23:59:997之间。
因此,如果四舍五入,则在998处将舍入到997。在999处,它将舍入到1月1日10000,这超出范围。 (sql-server中datetime的精度为3.33ms)
答案 1 :(得分:1)
有时候(我是说总是?)阅读documentation有很大帮助。
它说明:
日期范围:1753年1月1日至9999年12月31日
时间范围:00:00:00至23:59:59.997
关于时间对23:59:59.998
有效,即使有效范围长达997
毫秒,documentation仍然对此进行了解释
从23:59:59.995
到23:59:59.998
的时间存储为23:59:59.997
时间23:59:59.999
存储为00:00:00.000
+1天
然后,9999-12-31 23:59:59.999
存储为{strong>超出范围
10000-01-01 00:00:00.000
答案 2 :(得分:1)
datetime
仅精确到1/300秒,因此它只显示精确到0.00000,.003和.007秒的时间(最后是2秒的三分之二四舍五入为小数点后3位。
对于您的值'9999-12-31 23:59:59.999'
,SQL Server无法存储0.009,因此将其舍入到最接近的值,在这种情况下将是下一秒,因此日期为'10000-12-31 00:00:00.000'
,不能以任何日期和时间数据类型存储。
当您拥有.998
时,最接近的舍入值为.997
,因此不会发生错误。
如果您使用datetime2
也不会收到错误,因为该错误可以精确到秒的1/10000000:SELECT CAST('9999-12-31 23:59:59.999' AS datetime)
答案 3 :(得分:0)
根据documentation,四舍五入的秒数如下所示:
这是因为datetime数据类型不够精确,无法存储这些值。如果需要更高的精度,可以使用datetime2。
如果您想了解日期时间在SQL Server中的存储方式,建议您阅读本文:https://www.red-gate.com/simple-talk/sql/t-sql-programming/how-to-get-sql-server-dates-and-times-horribly-wrong/