【问题标题】:Rounding Issue in SQL compatibility level 130 vs 100SQL 兼容性级别 130 与 100 中的舍入问题
【发布时间】:2018-03-26 18:31:55
【问题描述】:

开发人员已联系我询问舍入问题。

我们计划将我们的数据库迁移到 SQL Server 2016,在新的 SQL 平台测试期间,我们发现 SQL Server 2016 在四舍五入方面比预期的差一点。

这种差异似乎是在更改/设置更高的兼容性级别时更改默认舍入方法的结果。

--SQL Server 2016 数据库兼容模式130

declare @a float = -0.0051175 -- 7 digits
declare @b float = 0.0051175

select round(@a, 6), round(@b, 6)

Result
------------------------------------
-0.005117 , 0.005117

--兼容模式100的SQL Server 2016数据库

declare @a float = -0.0051175 -- 7 digits
declare @b float = 0.0051175

select round(@a, 6), round(@b, 6)

Result
-----------------------------------
-0.005118   , 0.005118

有人对此有什么想法吗?

【问题讨论】:

  • 如果您真的担心数据的准确性,您应该停止使用浮点数。它不是一个精确的数据类型,并且会发生舍入错误。改用小数,那些舍入错误将不再发生。
  • 兼容级别 110 也是-0.005118, 0.005118
  • 谢谢,我才意识到这一点。在兼容级别 120 之前,它会按照我们预期的方式工作,然后随着 130 的变化而变化。
  • 2016 年优化器发生了重大变化,因此并不完全出乎意料。常量的表示在两个兼容级别下都是相同的,并且与 C# 加载的内容相同 (0x3F74F61672324C83),因此受到影响的是 ROUND,其确切算法没有记录。 FP 处理中有documented changes,但这不是记录在案的更改之一(并且跟踪标志 139 无效)。请注意,ROUND(0.0051175000000000005e, 6) 是“正确的”(0.0051175000000000005e 是下一个 FLOAT)。
  • 值得一提的是,常量转换为的FLOAT0.0051175 略小(所以它更像0.00511749999..),所以在某种意义上ROUND 是“正确的”。在另一种意义上,它不是——这完全取决于你如何准确地定义操作,而文档仔细没有做到这一点。

标签: sql sql-server tsql sql-server-2016 database-administration


【解决方案1】:

在我的博客上报道 - https://justdaveinfo.wordpress.com/2017/02/27/sql-server-2016-upgrading-to-compatability-level-130trace-flag-139-and-additional-one-off-dbcc-checks/

"https://support.microsoft.com/en-gb/help/4010261/sql-server-2016-improvements-in-handling-some-data-types-and-uncommon-

当升级到 SQL Server 2016 RTM CU3/SP1 并升级到数据库兼容性级别 130 时,应该执行额外的 DBCC 检查。

这些隐藏在跟踪标志 139 后面,应在将数据库兼容性级别更改为 130 的过程中临时启用。

Enable trace flag 139 by running DBCC TRACEON(139, -1).
Run DBCC CHECKDB/TABLE..WITH EXTENDED_LOGICAL_CHECKS to validate persisted structures
Run DBCC CHECKCONSTRAINTS commands (if rows are affected the associated where clause to identify the row will be returned).
Disable trace flag 139 by running DBCC TRACEOFF(139, -1)
Change the database compatibility level to 130.
REBUILD any structures that you identified in step 1.

数据库级别 130 中的表达式评估有改进,这会影响持久结构

Check constraints
Persisted Computed columns
Indexes using computing columns whether as part of the key or as included columns
Filtered indexes
Indexed views

在尝试修复问题之前升级到兼容性级别 130,以便使用新的表达式评估逻辑进行修复。

Check constraints – change data or drop/recreate constraint with new expression
Persisted Computed columns – Update a column referenced by the computed column to the same value to force recalcuation of the computed column
Index/filtered index/indexed views – Either A) Put db in single user mode and run DBCC CHECKTABLE with REPAIR_REBUILD B) ALTER INDEX…REBUILD and if supported in your edition of sql server consider adding the WITH (ONLINE=ON) clause.

注意:上面文章的附录 C/D 中有一些查询可用于帮助识别受影响的对象。”

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-08
    相关资源
    最近更新 更多