Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 为什么日期时间转换超出范围达999毫秒?_Sql Server_Datetime_Sql Server 2017 - Fatal编程技术网

Sql server 为什么日期时间转换超出范围达999毫秒?

Sql server 为什么日期时间转换超出范围达999毫秒?,sql-server,datetime,sql-server-2017,Sql Server,Datetime,Sql Server 2017,有人能解释一下我为什么会出错吗 结果将varchar数据类型转换为datetime数据类型 在超出范围的值中 当我在SQL Server 2017上执行以下代码时。我只得到了.999毫秒的错误 SELECT CAST('9999-12-31 23:59:59.999' AS DATETIME) 结果: 结果将varchar数据类型转换为datetime数据类型 在超出范围的值中 然后我试着: SELECT CAST('9999-12-31 23:59:59.998' AS DATETIME)

有人能解释一下我为什么会出错吗

结果将varchar数据类型转换为datetime数据类型 在超出范围的值中

当我在SQL Server 2017上执行以下代码时。我只得到了.999毫秒的错误

SELECT CAST('9999-12-31 23:59:59.999' AS DATETIME)
结果:

结果将varchar数据类型转换为datetime数据类型 在超出范围的值中

然后我试着:

SELECT CAST('9999-12-31 23:59:59.998' AS DATETIME)
SELECT CAST('9999-12-31 23:59:59.997' AS DATETIME)
结果:9999-12-3123:59:59.997

然后我试着:

SELECT CAST('9999-12-31 23:59:59.998' AS DATETIME)
SELECT CAST('9999-12-31 23:59:59.997' AS DATETIME)

结果:9999-12-31 23:59:59.997

根据文档,日期时间范围为1753年1月1日至9999年12月31日。同样基于文档,时间范围在00到23:59:997之间


因此,如果进行四舍五入,在998时,它将四舍五入到997。在999时,应将其四舍五入至1月1日10000,超出范围。(sql server中的日期时间精度为3.33毫秒)

根据文档,日期时间范围为1753年1月1日至9999年12月31日。同样基于文档,时间范围在00到23:59:997之间

因此,如果进行四舍五入,在998时,它将四舍五入到997。在999时,应将其四舍五入至1月1日10000,超出范围。(sql server中的datetime精度为3.33毫秒)

有时(我是说总是这样吗?)阅读数据会有很大帮助

它说:

日期范围:1753年1月1日至9999年12月31日

时间范围:00:00:00至23:59:59.997

关于
23:59:59.998
的有效时间,即使有效范围达到
997
ms,仍将在

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
被存储为
10000-01-01 00:00:00.000
,这超出了范围有时(我是说一直吗?)阅读帮助很大

它说:

日期范围:1753年1月1日至9999年12月31日

时间范围:00:00:00至23:59:59.997

关于
23:59:59.998
的有效时间,即使有效范围达到
997
ms,仍将在

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
存储为
10000-01-01 00:00:00.000
,超出范围

根据,百秒按如下方式四舍五入:

  • 999->000四舍五入(导致您的错误)
  • 998997996995->997
  • 992、993、994->993
  • 991,990->990
这是因为datetime数据类型不够精确,无法存储这些值。如果需要更高的精度,可以使用datetime2

如果您想了解datetime是如何存储在SQL Server中的,我推荐这篇文章:

根据,百秒四舍五入如下:

  • 999->000四舍五入(导致您的错误)
  • 998997996995->997
  • 992、993、994->993
  • 991,990->990
这是因为datetime数据类型不够精确,无法存储这些值。如果需要更高的精度,可以使用datetime2


如果您想了解datetime是如何存储在SQL Server中的,我推荐这篇文章:

datetime
只精确到1/300秒,因此它只显示精确到.000、.003和.007秒的时间(最后一个是三分之二秒,四舍五入到小数点后3位)

对于您的值
'9999-12-31 23:59:59.999'
SQL server无法存储0.009,因此它将舍入到最接近的值,在本例中是下一秒,使日期
'10000-12-31 00:00:00.000'
无法存储在任何日期和时间数据类型中

当您有
.998
时,最接近四舍五入的值是
.997
,因此不会发生错误


如果使用
datetime 2
也不会收到错误,因为它可以精确到1/10000000秒:
选择CAST('9999-12-31 23:59:59.999'作为datetime)
datetime
只精确到1/300秒,因此它只显示精确到.000、.003和.007秒的时间(最后是2/3秒,四舍五入到小数点后3位)

对于您的值
'9999-12-31 23:59:59.999'
SQL server无法存储0.009,因此它将舍入到最接近的值,在本例中是下一秒,使日期
'10000-12-31 00:00:00.000'
无法存储在任何日期和时间数据类型中

当您有
.998
时,最接近四舍五入的值是
.997
,因此不会发生错误


如果使用
datetime2
也不会收到错误,因为它可以精确到每秒的1/10000000:
选择CAST('9999-12-31 23:59:59.999'作为datetime)

正如我的问题SQL Server 2017中所述。正如我的问题SQL Server 2017中所述。谢谢你的回答。你能想出一个原因吗?这都是关于精度。SQL Server的精度不是1ms,而是3.33。这意味着它需要根据你的日期时间的位置进行取整。它使用normal转换规则。谢谢你的回答。你能想出一个原因吗?这都是关于精度。SQL Server的精度不是1ms,而是3.33。这意味着它需要根据日期时间的位置向上或向下取整。它使用正常的转换规则。