为何decimal(5,5)与decimal(5,0)间转换未触发错误?
为什么SQL Server中decimal(5,5)与decimal(5,0)之间的运算不会报错?
你的疑惑核心在于对decimal类型家族的隐式转换规则理解偏差,以下是具体解释:
1. decimal(p,s)的不同组合属于同家族的参数化类型
虽然SQL Server会将decimal(5,5)和decimal(5,0)视为不同的参数化类型,但它们都隶属于decimal/numeric这个数据类型大类。对于同属一个大类的不同参数化decimal类型,SQL Server完全支持它们之间的隐式转换,这和跨大类(比如decimal转varchar、decimal转datetime)的隐式转换规则是不同的。
2. 运算时的自动类型适配逻辑
当不同精度/小数位的decimal类型进行运算时,SQL Server会自动将它们转换到一个共同的目标类型,这个目标类型的精度和小数位是按照内置规则计算得出的:
- 对于加法/减法运算,目标类型的精度为
MAX(p1-s1, p2-s2) + MAX(s1, s2) + 1,小数位为MAX(s1, s2) - 以你的代码为例:
Number1是decimal(5,5):整数部分长度5-5=0,小数位长度5Number2是decimal(5,0):整数部分长度5-0=5,小数位长度0- 计算后目标类型精度为
MAX(0,5) + MAX(5,0) +1 = 5+5+1=11,小数位为MAX(5,0)=5,即结果类型为decimal(11,5),最终值为5.22300
3. 对文档描述的澄清
- 文档中“每种组合视为不同的数据类型”,是指在类型系统的元数据层面它们是不同的(比如在定义变量、表列时是区分的),但这并不影响同家族内的隐式转换支持。
- 文档中“不支持的隐式转换则报错”,针对的是跨数据大类的转换场景,而非同decimal家族内的不同参数化类型转换。你提到的图示大概率是跨大类的转换表,同家族内部的转换并不在“不支持”的范畴里。
验证代码运行结果
执行你的代码后,你可以通过以下语句查看结果的具体类型:
SELECT SQL_VARIANT_PROPERTY((Number1 + Number2), 'BaseType') AS BaseType, SQL_VARIANT_PROPERTY((Number1 + Number2), 'Precision') AS Precision, SQL_VARIANT_PROPERTY((Number1 + Number2), 'Scale') AS Scale FROM #t1;
返回结果会显示类型为decimal,精度11,小数位5,这也证实了SQL Server自动完成了类型转换和运算。
内容的提问来源于stack exchange,提问作者Alfredo
相关产品推荐
相关产品推荐

