日期:2014-05-18  浏览次数:20713 次

困扰3天的bug,请高手进来看看
设计的思路是这样的,一共二个表 fee_user , excess_fee_user
fee_user的数据是通过trigger时时插入的。

然后把fee_user的fee_code 每2分钟自动汇总一下插到 excess_fee_user表
因为数据量比较大,boss要求fee_code的扫描要尽量少,所以我过程中总是对一段数据进行统计。
比如第一次是汇总1到20条数据,那第二次就只能21到目前最大的id值汇总,下次又是对刚才最大的值到目前最大值的汇总
但是不知道哪里有bug,常常在excess_fee_user这张汇总表里的数据成倍的大于fee_code这张源表
请高手里帮看下。

fee_user 的字段有 serial(这是自增例),fee_terminal_id,fee_code,icpid,insert_time
excess_fee_user serial(这是自增例),fee_terminal_id,sum_fee,icpid,insert_time
serial_id (记录id值的) id,(这是自增例) serial(这是记录本次汇总值的)






以下是过程代码

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go




create proc [dbo].[excess_fee] as


declare @id int, @nextID int
select @id = isnull(max(serial), 0) from fee_user with (nolock)  
select @nextID = isnull(max(serial),0) from serial_id with (nolock)

print @id
print @nextid


update excess_fee_user 
set sum_fee = a.sum_fee + b.sum_fee
from excess_fee_user a join 
(select icpid, fee_terminal_id, insert_time, sum(fee_code) as sum_Fee from fee_user (nolock) 
where serial > @nextID and serial<=@id
group by icpid, fee_terminal_id, insert_time) as b
on a.fee_terminal_id=b.fee_terminal_id and a.icpid=b.icpid and a.insert_time=b.insert_time




insert into excess_fee_user (fee_terminal_id,sum_fee,icpid,insert_time)
select a.fee_terminal_id, a.sum_fee, a.icpid, a.insert_time 
from 
(select icpid, fee_terminal_id, insert_time, sum(fee_code) as sum_Fee from fee_user (nolock) 
where serial > @nextID and serial<=@id
group by icpid, fee_terminal_id, insert_time) as a
left join 
excess_fee_user b
on a.fee_terminal_id=b.fee_terminal_id and a.icpid=b.icpid and a.insert_time=b.insert_time
where b.fee_terminal_id is null


insert into serial_id (serial)
values(@id)



SET ANSI_NULLS OFF







------解决方案--------------------
逻辑上应该没问题。

问题可能出在insert_time这个字段,不知道什么类型的。

按照上述的SQL逻辑,应该不是datetime类型,而是一个字符型的时间字段。

关键就在这了,insert_time精确到小时、日、星期或是其它。
------解决方案--------------------
将汇总过的做个标记,
下一汇总从新的没有做过标记记录开始汇总?
------解决方案--------------------
把这段生成临时表处理,在语句中调用了两次
(select icpid, fee_terminal_id, insert_time, sum(fee_code) as sum_Fee
from fee_user (nolock)
where serial > @nextID and serial <=@id 
group by icpid, fee_terminal_id, insert_time