为什么某些数值的隐式转换有效而其他数值无效?
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%';
在这种情况下,将表达式显式转换为所需的输出数据类型,而不仅仅是
依赖于数据类型的隐式转换。可以参考网站上的数据类型转换表,但是这里不知道隐式转换后的结果数据类型。
它会尝试将您的字符串转换为 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(?, ?)
具有适当的比例和精度)。
这对我来说今天才刚刚开始发生。
如果我运行这个:
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%';
在这种情况下,将表达式显式转换为所需的输出数据类型,而不仅仅是 依赖于数据类型的隐式转换。可以参考网站上的数据类型转换表,但是这里不知道隐式转换后的结果数据类型。
它会尝试将您的字符串转换为 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(?, ?)
具有适当的比例和精度)。