为什么某些数值的隐式转换有效而其他数值无效?

Why does implicit conversion from some numeric values work but not others?

这对我来说今天才刚刚开始发生。

如果我运行这个:

select '185.37' * 2.00 
select '0.16' * 2.00 

第一次查询returns这个错误:

Arithmetic overflow error converting varchar to data type numeric.

第二个查询 returns 0.32 符合预期。

这是在 SQL 服务器 15.0.2080.9.

我知道我可以通过转换为小数或数字来解决问题,但为什么只有较大的数字才会出现错误?为什么今天才开始出现这种情况?此查询已用作 ETL 的一部分,我们在过去几年中一直在使用该查询,而没有进行任何更改。

对于下面提到的 SQL 左侧是 varchar 数据类型,右侧是数字数据类型 numeric(3,2) .

select '185.37' * 2.00

在从 varchar 隐式转换为 numeric 之后,result data type will be numeric(3,2) but actual result 370.74 need a datatype of numeric(5,2) 因此该表达式因溢出错误而失败。您可以在下面的示例代码中看到这些数据类型。

select 2.00 as colDatatype,185.37 as colDatatype2, 370.74 as colDatatype3 into #tempdata

SELECT * FROM tempdb.INFORMATION_SCHEMA.columns WHERE table_name like'#tempdata%';

在这种情况下,将表达式显式转换为所需的输出数据类型,而不仅仅是 依赖于数据类型的隐式转换。可以参考网站上的数据类型转换表,但是这里不知道隐式转换后的结果数据类型。

Microsoft link

它会尝试将您的字符串转换为 numeric(3,2),因为这是乘法 1 右边的类型。如果你可以强制你的值是一个更大的数字类型:

select '185.37' * (102.00 - 100.00)

然后它工作正常(产生 370.74),因为它现在将尝试将其转换为 numeric(5,2)

不过,我不是通过技巧来完成的,而是为此选择一个合适的数字类型,然后 明确地 执行所需的转换,以更好地记录您想要发生的事情:

select CONVERT(numeric(5,2),'185.37') * 2.00

1它有一个higher precedence.

编辑(戈登·利诺夫):

SQL 服务器为此目的使用类型优先级在 documentation:

中明确说明

For comparison operators or other expressions, the resulting data type will depend on the rules of data type precedence.

可能只是有点混乱,因为文档并不清楚数字的小数位数和精度是类型的一部分(也就是说,转换的是 numeric(3, 2) 而不是 numeric(?, ?) 具有适当的比例和精度)。