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

求存储过程,两表某相减后同时更新,关系一对多!
折腾死我了啊,求大家帮忙啊。结构这样:

A表三个字段:欠款人,欠款种类,欠款金额。
B表两个字段:还款人,还款金额。

问题:数据收起完成后,用B表中的还款金额逐条还A表中的欠款。如果足额,则全部还上;如果不够,则还到哪条欠款算哪条,有多少还多少,不留还款余额。两表用还款人和欠款人关联(同为人员ID号)。

例如A表数据:

1001 201 37.57
1001 207 21.44
1001 217 131.96
1002 201 31.43
1002 207 25.40
1003 207 29.11


B表数据:

1001 100.00
1002 80.00

最终更新后要求:

A表数据:

1001 201 0.00
1001 207 0.00
1001 217 90.97
1002 201 0.00
1002 207 0.00
1003 207 29.11

B表数据:

1001 0.00
1002 23.17

求存储过程啊!谢谢各位了。

------解决方案--------------------
第一种方法,使用存储过程。比较直观的话, 可以使用CURSOR。
大致如下:
declare cursor CURSOR FOR
SELECT ID FROM B.ID
ORDER BY ID;

OPEN cursor;

FETCH NEXT FROM cursor;
--现在指向了第一个ID 1001
然后在A表中操作, A表的操作可以再次使用CURSOR,或者使用临时表,每次都把CURSOR指向的ID从A表中读取到临时表,然后数额减去临时表中top 1的数据,临时表删除top 1的数据。

FETCH NEXT FROM cursor;
END

CLOSE cursor;
DEALLOCATE cursor;

第二种方法,使用触发器:
做法和第一种相同



------解决方案--------------------
SQL code

create table tba(cardid varchar(10),cid int,amount decimal(18,2))
insert into tba
select '1001' ,201 ,37.57 union all
select '1001' ,207 ,21.44 union all
select '1001' ,217 ,131.96 union all
select '1002' ,201 ,31.43 union all
select '1002' ,207 ,25.40 union all
select '1003' ,207 ,29.11
go

create table tbb(cardid varchar(10),amount decimal(18,2))
insert into tbb
select '1001' ,100.00 union all
select '1002' ,80.00
go

declare @cardid varchar(10)
declare @amount decimal(18,2)
declare @cat decimal(18,2)

select * into #tba
from (
    select cardid,sum(amount) amount from tba group by cardid
) t

update a
set @amount = (case when b.cardid <> isnull(@cardid,'') then b.amount else @amount end),
    @cat = (case when b.cardid <> isnull(@cardid,'') then 0 else @cat end),
    @cardid = b.cardid,
    @amount = @amount - @cat,
    a.amount = (case when @amount >=0 then
                        case when @amount >= a.amount then 0
                             when @amount < a.amount then a.amount - @amount end
                    else a.amount end),
    @cat = a.amount
from tbb b join tba a on b.cardid = a.cardid
where a.amount <> 0 and b.amount <> 0

select * from tba

update b
set b.amount = (case when b.amount < isnull(a.amount,0) then 0
                     else b.amount - isnull(a.amount,0) end)
from #tba a join tbb b on a.cardid = b.cardid

select * from tbb

drop table tba,tbb,#tba

/**********************

cardid     cid         amount
---------- ----------- ---------------------------------------
1001       201         0.00
1001       207         0.00
1001       217         90.97
1002       201         0.00
1002       207         0.00
1003       207         29.11

(6 行受影响)

(2 行受影响)

cardid     amount
---------- ---------------------------------------
1001       0.00
1002       23.17

(2 行受影响)