【发布时间】:2012-11-21 00:10:59
【问题描述】:
这是对我的问题Reference a column and update it in the same statement 的跟进。我现在正在尝试使用局部变量并在同一个更新语句中对其进行更新。
declare @tmp table (ID int primary key, UNPAID money)
insert into @tmp select 1, 31.63
insert into @tmp select 2, 49.20
insert into @tmp select 3, 99.00
insert into @tmp select 4, 41.00
declare @paymentAmmount money
select @paymentAmmount = SUM(UNPAID) from @tmp
declare cur_oustandingAR cursor local static for select ID from @tmp order by ID
open cur_oustandingAR
declare @currentID int
fetch next from cur_oustandingAR into @currentID
while (@@fetch_status = 0 and @paymentAmmount > 0)
begin
begin
update @tmp
set UNPAID = case when @paymentAmmount > UNPAID then 0 else UNPAID - @paymentAmmount end,
@paymentAmmount = case when @paymentAmmount > UNPAID then @paymentAmmount - UNPAID else 0 end
where ID = @currentID
end
fetch next from cur_oustandingAR into @currentID
end
select * from @tmp
select @paymentAmmount as LeftoverPayment
您可以运行查询here,这是它给出的结果
身份证未付 ------------ --------- 1 0.00 2 0.00 3 58.00 4 41.00 剩余付款 --------------- 0所有值都应为 0,最后的 @paymentAmmount 也应为 0。是什么问题导致无法正确应用这些值?
附:我知道如何fix it,只需将一个查询分解为以下 3 个查询,但我想将其作为一个查询进行,因此我不需要针对真实表进行尽可能多的查找
select @oldUnpaid = UNPAID from @tmp where ID = @currentID
update @tmp
set UNPAID = case when @paymentAmmount > UNPAID then 0 else UNPAID - @paymentAmmount end
where ID = @currentID
select @paymentAmmount = case when @paymentAmmount > @oldUnpaid then @paymentAmmount - @oldUnpaid else 0 end
我只是想知道为什么我目前正在做的事情不起作用。
【问题讨论】:
-
为什么要使用游标? (顺便说一句,缺少关闭和解除分配)
-
@MitchWheat 1) 声明为本地的游标不需要关闭/解除分配:P 2) 这是对更大查询的简化重新创建。我需要先将付款应用到最早的费用来核对付款。
-
“声明为本地的游标不需要关闭/解除分配” - 你有这方面的参考吗?
-
@MitchWheat MSDN "游标在批处理、存储过程或触发器终止时被隐式释放,除非游标在 OUTPUT 参数中传回。如果传回在 OUTPUT 参数中,当引用它的最后一个变量被释放或超出范围时,游标被释放。"
-
"你没有明确地必须" ~= "你不应该。"我总是关闭并取消分配我的游标,特别是如果它们是更大过程的一部分。为什么要让它们持续到你不再需要它们的地步?
标签: sql sql-server sql-server-2008-r2 sql-update