首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

存储过程中字段计算,传入的小数在计算前就被四舍五入的有关问题

2012-12-19 
存储过程中字段计算,传入的小数在计算前就被四舍五入的问题。存储过程部分代码如下:BasicUnit_1在数据库中

存储过程中字段计算,传入的小数在计算前就被四舍五入的问题。
存储过程部分代码如下:
BasicUnit_1在数据库中为 money类型
我这里的@BasicUnit_1 是用来计算BasicUnit_1字段的倍率。
根据出厂价*倍率来批量设置 BasicUnit_1 的价格。
BasicUnit_1 = ROUND((FactoryPrice * @BasicUnit_1),2)
用了好些保留两位的方法,也测试了单纯的 FactoryPrice * @BasicUnit_1 计算
假设 FactoryPrice = 4 传入 @BasicUnit_1 = 1.2 时   BasicUnit_1结果为4
传入 @BasicUnit_1 = 1.5 时   BasicUnit_1结果为8
应该是@BasicUnit_1 在计算前就被进行了四舍五入。以前没遇到过这个问题,求解决。

另外我这里用到了临时表来暂存一个批量修改的ID列表。
这个条件会被执行到20来次的价格设置条件,为避免相同的条件查询就做了个临时表。

本来想用表变量,无奈不能用
EXEC来执行带表变量的SQL语句。

也想过用条件判断字符串拼接来做更新语句,代码实在有些长。这个功能很少用到。
不知道这样做性能如何。


ALTER procedure [dbo].[UpdatePrice]--更新产品价格
(
--价格信息
@RowCounts int=0 output,--返回受影响的行数
@FactoryPrice Money = 0,--出厂价格
@BasicUnit_1 Decimal = 0,
@BasicUnit_2 Decimal = 0,
@BasicUnit_3 Decimal = 0,
@BasicUnit_4 Decimal = 0,
@BasicUnit_5 Decimal = 0,
@BasicUnit_6 Decimal = 0,
@Unit2_1 Decimal = 0,--包装2价格
@Unit2_2 Decimal = 0,
@Unit2_3 Decimal = 0,
@Unit2_4 Decimal = 0,
@Unit2_5 Decimal = 0,
@Unit2_6 Decimal = 0,
@Unit3_1 Decimal = 0,--包装3价格
@Unit3_2 Decimal = 0,
@Unit3_3 Decimal = 0,
@Unit3_4 Decimal = 0,
@Unit3_5 Decimal = 0,
@Unit3_6 Decimal = 0,
@strWhere varchar(1000)
)

AS

SET NOCOUNT ON
SET ANSI_WARNINGS OFF
SET XACT_ABORT ON
DECLARE @Sql VARCHAR(1000)

CREATE TABLE #TempTable (ProductID INT)
SET @Sql = 'INSERT INTO #TempTable (ProductID) SELECT (ProductID) FROM V_Products WHERE '+ @strWhere
EXEC(@Sql)

BEGIN TRAN
SET @RowCounts = @@RowCount

if(@FactoryPrice != 0)
begin
UPDATE ProductPrice SET FactoryPrice=@FactoryPrice where ProductID IN (select ProductID from #TempTable)
SET @RowCounts = @RowCounts + @@RowCount
end
----------------包装单位1价格----------------------------
IF ISNULL(@BasicUnit_1, 0) != 0
BEGIN
UPDATE ProductPrice SET BasicUnit_1 = ROUND((FactoryPrice * @BasicUnit_1),2) where ProductID IN (select ProductID from #TempTable)
SET @RowCounts = @RowCounts + @@RowCount
END
COMMIT TRAN
PRINT(@RowCounts)

[最优解释]
根据我以前给银行做系统的经验,由于都是上千亿,并且最后汇总不能误差大于1块钱。所以当时公司规定,一般都保留到小数点6位,然后在最后一步汇总的时候才convert来截取小数位。这样误差会小很多。如果过早四舍五入,当数据量大的时候,误差就比较明显。
[其他解释]
 @BasicUnit_1  --> 这个变量 你设什么类型? 试试 numeric(18,2)
[其他解释]
declare @variant decimal(p,s)

decimal默认为decimal(18,0)
[其他解释]
晕死,我在建表的时候是 (18,2)的 这里没想到~ 
[其他解释]
引用:
根据我以前给银行做系统的经验,由于都是上千亿,并且最后汇总不能误差大于1块钱。所以当时公司规定,一般都保留到小数点6位,然后在最后一步汇总的时候才convert来截取小数位。这样误差会小很多。如果过早四舍五入,当数据量大的时候,误差就比较明显。


我也想精确点的,结果犯了个很低级的错误~ 没问前还没发现错误在哪里。

大侠帮我看看这样的临时表,性能方面是否可行。
每次执行存储过程时候 这个条件可能会被用到很多次。  如果多用户执行这个存储过程 临时表应该是互相独立的吧。 我记得是根据每个用户的Session来建立的。


[其他解释]
临时表是根据每个connection来建立的
[其他解释]
引用:
引用:
根据我以前给银行做系统的经验,由于都是上千亿,并且最后汇总不能误差大于1块钱。所以当时公司规定,一般都保留到小数点6位,然后在最后一步汇总的时候才convert来截取小数位。这样误差会小很多。如果过早四舍五入,当数据量大的时候,误差就比较明显。
我也想精确点的,结果犯了个很低级的错误~ 没问前还没发现错误在哪里。

大侠帮我看看这样的临时表,……
对,临时表是每个连接独有的,除非你使用了全局临时表也就是##开头的。

热点排行