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

sql server 分期付款 触发器设计
事例如下:
现有一分期应收款表BS
编号             应收款年度               应收款时间         应收款金额             实收款时间             实收款金额
0001             2005.01.01-2005.12.30       2005-02-01         50000.00
0001             2006.01.01-2006.12.30       2006-02-01         90000.00
0001             2007.01.01-2007.12.30       2007-02-01         50000.00
...

实收款表Charge
编号             实收款时间             实收款金额  


则:
对0001收到第一笔款50000元(Charge表),那么应收款表0001第一笔实收款即为50000(BS表);如果收到40000(Charge表),则第一笔实收款为40000(BS表);如果收到100000(Charge表),则第一笔实收款是50000(BS表),第二笔实收款是50000(BS表)...然后是陆续的实收款,将自动的按时间排序将前面的款项结清,保持最新的待结应收款,对实收款表Charge进行增加编辑删除....

------解决方案--------------------
create trigger tr_Charge_Insert
on Charge
for insert
as

if (select count(*) from inserted)> 1
begin
RAISERROR ( '一次只能插入一条记录 ', 16, 1)
ROLLBACK TRANSACTION
return
end
set nocount on

declare @实收款金额 numeric(18,2)
declare @编号 varchar(20)
declare @实收款时间 datetime
declare @temp numeric(18,2)

select @编号=编号,@实收款时间=实收款时间,@实收款金额=实收款金额 from inserted

update bs
set @temp=case when @实收款金额> 应收款金额-isnull(实收款金额,0) then 应收款金额-isnull(实收款金额,0) else @实收款金额 end,
@实收款金额=@实收款金额-@temp,
实收款时间=case when @temp> 0 then @实收款时间 else 实收款时间 end,
实收款金额=case when @temp> 0 then isnull(实收款金额,0)+@Temp else 实收款金额 end
where 编号=@编号 and 应收款金额-isnull(实收款金额,0)> 0

go

--要求:BS表以(编号,应收款时间)作为聚集索引



------解决方案--------------------
--未测试,你测试下
--修改的情况将非常复杂,建议Charge表不允许修改和删除,有错误只能用另一条数据充


------解决方案--------------------
触发器未考虑充数的情况,假设实收款金额> 0

------解决方案--------------------
如果需要修改删除,不如去掉BS表的实收款时间 实收款金额字段,也不需要触发器

问题就变成一个非配查询的问题

BS
编号 应收款年度 应收款时间 应收款金额
0001 2005.01.01-2005.12.30 2005-02-01 50000.00
0001 2006.01.01-2006.12.30 2006-02-01 90000.00
0001 2007.01.01-2007.12.30 2007-02-01 50000.00
...

Charge
编号 实收款时间 实收款金额
0001 2005-3-1 40000
0001 2005-4-1 100000
0001 2007-4-1 50000

结果
编号 应收款年度 应收款时间 应收款金额 实收款时间 实收款金额
0001 2005.01.01-2005.12.30 2005-02-01 50000.00 2005-4-1 50000
0001 2006.01.01-2006.12.30 2006-02-01 90000.00 2005-4-1 90000
0001 2007.01.01-2007.12.30 2007-02-01 50000.00 2007-4-1 50000


------解决方案--------------------
这个查询可以用个存储过程来解决,用临时表和游标是可以写出来的,出错机会会少很多



------解决方案--------------------
你原来的数据是冗余的,而且需要修改,这样维护一致性的代价有点大