简体   繁体   English

SQL 服务器兼容性造成问题

[英]SQL Server compatibility creates issue

We have changed the SQL Server compatibility from 100 to 130 the below code in our stored procedure behaves differently:我们已将 SQL 服务器兼容性从 100 更改为 130,我们存储过程中的以下代码表现不同:

DECLARE @i decimal(4, 0) = 1,
        @j decimal(4, 1) = 0.5

SELECT SUM(@i) - SUM(@j)

Result of the select: select 的结果:

  • Compatibility Level 100: 0兼容性级别 100:0
  • Compatibility Level 130: 1兼容级别 130:1

We are not sure how many calculation we have in our code like this.我们不确定我们的代码中有多少这样的计算。

Is there any setting in the SQL Server database we can make to work same as compatibility level 100?我们可以使 SQL 服务器数据库中的任何设置与兼容级别 100 一样工作吗?

Let's try to use suitable data types: https://stackoverflow.com/a/7158770/5309660让我们尝试使用合适的数据类型: https://stackoverflow.com/a/7158770/5309660

DECLARE @i decimal(4, 0) = 1,
        @j decimal(4, 1) = 0.5

SELECT CAST(SUM(@i) AS REAL) - CAST(SUM(@j) AS REAL)

In previous versions of SQL Server, the "scale" of the result was not following the rules. SQL Server 之前的版本中,结果的“scale”不符合规则。 This was corrected in a later version (I don't remember which version changed).这在后来的版本中得到了纠正(我不记得哪个版本发生了变化)。

No, there is no way to change it back.不,没有办法改回来。

https://learn.microsoft.com/en-us/sql/t-sql/data-types/precision-scale-and-length-transact-sql?view=sql-server-ver16 https://learn.microsoft.com/en-us/sql/t-sql/data-types/precision-scale-and-length-transact-sql?view=sql-server-ver16

To simplify things a bit the gist of the issue is that Compatibility Level 120为了简化事情,问题的要点是兼容级别 120

DECLARE @A decimal(38,0) = 1, 
        @B decimal(38,1) = 0.5

SELECT @A - @B /*Returns 0*/

Compatibility Level 130兼容级别 130

DECLARE @A decimal(38,0) = 1, 
        @B decimal(38,1) = 0.5

SELECT @A - @B /*Returns 1*/

The datatype of the result is decimal(38,0) in both cases.在这两种情况下,结果的数据类型都是decimal(38,0)

Your question is not asking how to get the mathematically correct result of 0.5 .您的问题不是询问如何获得0.5的数学上正确的结果。 You are just asking how to get the compat 120 behaviour.您只是在询问如何获得 compat 120 行为。

You can't without setting that compatibility level I'm afraid.恐怕你不能不设置那个兼容性级别。

Note in both compat levels注意两个兼容级别

SELECT CONVERT(decimal(38,0), 0.5) 

Returns 1 so this should really be the "expected" result in both cases.返回1所以这应该是两种情况下的“预期”结果。

In the 100 case I assume what it actually does is convert the operand first .在 100 的情况下,我假设它实际做的是首先转换操作数。 ie as below即如下

SELECT @A - CONVERT(decimal(38,0), @B)

I think the only time it will make a difference in this case is when one of the operands has decimal .5 and you are subtracting it.认为在这种情况下唯一会有所不同的是当其中一个操作数具有小数点.5并且您正在减去它时。 If @B is 0.6 for example it makes no odds if this gets rounded up to the closest integer before the subtraction or the result of the subtraction is rounded down to the closest integer after it.例如,如果@B0.6 ,则在减法之前向上舍入到最接近的 integer 或减法的结果向下舍入到最接近的 integer 后,它没有任何几率。

The SQL Server 2016 breaking changes does call out SQL Server 2016 重大更改确实调用

Under database compatibility level 130, operations that perform implicit conversions between certain numeric and datetime data types show improved accuracy and can result in different converted values.在数据库兼容级别 130 下,在某些数字和日期时间数据类型之间执行隐式转换的操作显示出更高的准确性,并可能导致不同的转换值。

Although it doesn't explicitly mention this case when clicking through .虽然它在点击时没有明确提到这种情况。

Is there any setting in the SQL Server database we can make to work same as compatibility level 100?我们可以使 SQL 服务器数据库中的任何设置与兼容级别 100 一样工作吗?

Only by setting the compatibility level.只能通过设置兼容级别。 It is exactly this sort of thing that the compatibility level mechanism is for (to give you time to identify and adjust any affected code)兼容性级别机制正是针对此类事情(让您有时间识别和调整任何受影响的代码)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM