首页新闻找找看学习计划

一个sql存储过程循环遍历赋值的问题

1
悬赏园豆:5 [已解决问题] 解决于 2011-01-10 11:05

要实现的效果是:如果传进去的@cyid=0,则把chengyuan表中所有成员的cyoffer 和cyreturn改变;如果传进去的@cyid!=0,且@cyid是chengyuan表中的成员id,则,改变当前id对应的cyoffer 和cyreturn值。

结算存储过程如下

---------------------------成员结算----------------
create proc sp_jiesuan
@cyid int ,--要结算的成员id,如果id为零则将所有成员结算
@jiesuane numeric(18,2)--结算额
as
set nocount on
set rowcount 0
set transaction isolation level read uncommitted
declare @error_no integer, --错误号
@error_info varchar(255)---错误信息

select @error_no =0,
@error_info =''

select @cyid=isnull(@cyid,0),
@jiesuane =isnull(@jiesuane,0.00)
begin transaction
declare @yingfu numeric(18,2)
if @cyid=0

begin
declare @icy int
select @icy=1
while @icy<=(select count(cyid) from chengyuan)

begin
declare @id int
select @id=(select top 1 cyid from chengyuan where cyid not in(
select top (@icy-1) cyid from chengyuan order by cyid asc) order by cyid asc),
@yingfu= ((select cyreturn from chengyuan where cyid=@id)-(select cyoffer from chengyuan where cyid=@id))
if @yingfu>@jiesuane
update chengyuan set cyoffer=cyoffer+@jiesuane where cyid=@id
else if @yingfu=@jiesuane
update chengyuan set cyoffer=0 ,cyreturn=0 where cyid=@id
else if @yingfu<@jiesuane
update chengyuan set cyoffer=@jiesuane-@yingfu ,cyreturn=0 where cyid=@id

set @icy=@icy+1
end

end
else

--declare @icy1 int
--
select @icy1=1
if @cyid in (select cyid from chengyuan)

begin
select @yingfu=(select cyreturn from chengyuan where cyid=@cyid)-(select cyoffer from chengyuan where cyid=@cyid)
if @yingfu>@jiesuane
update chengyuan set cyoffer=cyoffer+@jiesuane where cyid=@cyid
else if @yingfu=@jiesuane
update chengyuan set cyoffer=0 ,cyreturn=0 where cyid=@cyid
else if @yingfu<@jiesuane
update chengyuan set cyoffer=@jiesuane-@yingfu ,cyreturn=0 where cyid=@cyid
end

commit transaction
if @error_no!=0
return @error_no
return 0

问题是:其中当@cyid=0时,为什么chengyuan表中cyid=1的那条数据没有改变,其他的数据均改变了?

寒狐的主页 寒狐 | 菜鸟二级 | 园豆:433
提问于:2011-01-07 09:29
< >
分享
最佳答案
1

你的语句需要修改 因为你在执行

select @id=(select top 1 cyid from chengyuan where cyid not in(
select top (@icy-1) cyid from chengyuan order by cyid asc) order by cyid asc),
@yingfu= ((select cyreturn from chengyuan where cyid=@id)-(select cyoffer from chengyuan where cyid=@id))

这一段的时候 第一次循环时@id在(select cyreturn from chengyuan where cyid=@id )里面为null值的

所以@yingfu 也等于null  当然后面的update语句@id才是第一次查询出来的值

等到第二次循环后在(select cyreturn from chengyuan where cyid = @id) @id等于第一次循环的值后面的update语句@id才是第二次查询出来的值

(注意:不管declare @icy int循环内还是循环前,值一样)

 

收获园豆:5
追索 | 小虾三级 |园豆:625 | 2011-01-07 10:30
你分析的很正确,但是怎么解决这个问题呢?
寒狐 | 园豆:433 (菜鸟二级) | 2011-01-07 12:41
分两个步骤,先执行 select @id=(select top 1 cyid from chengyuan where cyid not in( select top (@icy-1) cyid from chengyuan order by cyid asc) order by cyid asc) 再执行 select @yingfu= ((select cyreturn from chengyuan where cyid=@id)-(select cyoffer from chengyuan where cyid=@id))
追索 | 园豆:625 (小虾三级) | 2011-01-07 14:55
其他回答(1)
0

select 、update等SQL语句都是对行同时操作的。如一个表test(a,b)

a   b

1  2

update test set a=b,b=a where a=1后,

结果:

a  b

2  1

eesee | 园豆:136 (初学一级) | 2011-01-09 13:25
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册