decimal和money相互运算的隐式数据转换

qq_38827481 2017-10-12 09:39:09
大家好,我在进行decimal和money运算是发现,decimal和money之间,decimal(18,4)和decimal(18,8)之间分别做乘(*)和除(/),结果的数据类型会不一样而且看不懂,例子:
DECLARE @A MONEY = 1.2,@B DECIMAL(18,2) = 2,@C DECIMAL(18,4) = 2,@D DECIMAL(18,8) = 2
SELECT @A/@B AS [MONEY/DECIMAL(18,2)]
,@A*@B AS [MONEY*DECIMAL(18,2)]
,@A/@C AS [MONEY/DECIMAL(18,2)]
,@A*@C AS [MONEY*DECIMAL(18,2)]
,@A/@D AS [MONEY/DECIMAL(18,2)]
,@A*@D AS [MONEY*DECIMAL(18,2)]
,@B/@C AS [DECIMAL(18,2)/DECIMAL(18,4)]
,@B*@C AS [DECIMAL(18,2)*DECIMAL(18,4)]
,@B/@D AS [DECIMAL(18,2)/DECIMAL(18,8)]
,@B*@D AS [DECIMAL(18,2)*DECIMAL(18,8)]
,@C/@C AS [DECIMAL(18,4)/DECIMAL(18,4)]
,@C*@C AS [DECIMAL(18,4)*DECIMAL(18,4)]
...全文
377 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
OwenZeng_DBA 2017-10-12
  • 打赏
  • 举报
回复
引用 楼主 qq_38827481 的回复:
大家好,我在进行decimal和money运算是发现,decimal和money之间,decimal(18,4)和decimal(18,8)之间分别做乘(*)和除(/),结果的数据类型会不一样而且看不懂,例子: DECLARE @A MONEY = 1.2,@B DECIMAL(18,2) = 2,@C DECIMAL(18,4) = 2,@D DECIMAL(18,8) = 2 SELECT @A/@B AS [MONEY/DECIMAL(18,2)] ,@A*@B AS [MONEY*DECIMAL(18,2)] ,@A/@C AS [MONEY/DECIMAL(18,2)] ,@A*@C AS [MONEY*DECIMAL(18,2)] ,@A/@D AS [MONEY/DECIMAL(18,2)] ,@A*@D AS [MONEY*DECIMAL(18,2)] ,@B/@C AS [DECIMAL(18,2)/DECIMAL(18,4)] ,@B*@C AS [DECIMAL(18,2)*DECIMAL(18,4)] ,@B/@D AS [DECIMAL(18,2)/DECIMAL(18,8)] ,@B*@D AS [DECIMAL(18,2)*DECIMAL(18,8)] ,@C/@C AS [DECIMAL(18,4)/DECIMAL(18,4)] ,@C*@C AS [DECIMAL(18,4)*DECIMAL(18,4)]
decimal的优先级别是高于money的 ,隐式转换会将优先级较低的数据类型转换为优先级较高的数据类型。优先级别参考下面链接 https://docs.microsoft.com/zh-cn/sql/t-sql/data-types/data-type-precedence-transact-sql
听雨停了 2017-10-12
  • 打赏
  • 举报
回复

--假定运算数分别为@d1(精度为p1,小数位数为s1),@d2(精度为p2,小数位数为s2), 
--则SQL内部的转换规则如下(我们知道精度的最大值是38,当运算结果的精度大于38时,
--SQL将会截短小数部分,以保证整数部分不会被截断。):
--money的精度是19,小数位数是4

-- @d1*@d2
--运算结果的精度 = p1 + p2 + 1  --注:当值大于38时,取38
--运算结果的小数位数
--      当精度值不大于38(或s1+s2<=6)时 = s1 + s2 --也就是取两者小数位数之和
--      当精度值大于38时 = max(6, s1+s2-(p1+p2+1-38))
declare @d1 numeric(12,6),@d2 numeric(10,7)  
select @d1=100,@d2=200  
select 精度=SQL_VARIANT_PROPERTY(@d1*@d2,'Precision'),小数位数=SQL_VARIANT_PROPERTY(@d1*@d2,'Scale'),运算结果=@d1*@d2  
/* 
精度             小数位数           运算结果 
---------------- ------------------ ----------------- 
23               13                 20000.0000000000000 
*/ 

--@d1/@d2
--运算结果的精度 = p1 - s1 + s2 + max(6, s1 + p2 + 1)  --注:当值大于38时,取38
--运算结果的小数位数 
--      当精度值不大于38时 = max(6, s1 + p2 + 1)
--      当精度值大于38时 = max(6, s1+p2+1-(精度-38))
declare @d1 numeric(12,6),@d2 numeric(10,7)  
select @d1=100,@d2=200  
select 精度=SQL_VARIANT_PROPERTY(@d1/@d2,'Precision'),小数位数=SQL_VARIANT_PROPERTY(@d1/@d2,'Scale'),运算结果=@d1/@d2  
/* 
精度             小数位数           运算结果 
---------------- ------------------ ----------------- 
30               17                 0.50000000000000000 
*/  

27,579

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 应用实例
社区管理员
  • 应用实例社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧