2012-11-21 4 views
0

Ceci est une sorte de suivi de ma question Reference a column and update it in the same statement. J'essaye maintenant d'employer une variable locale et l'ai mise à jour dans la même instruction de mise à jour.Comportement de mise à jour impaire lors de la mise à jour lors de l'utilisation d'une variable

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 

Vous pouvez exécuter la requête here, voici les résultats qu'il donne

 
ID   UNPAID 
----------- --------------------- 
1   0.00 
2   0.00 
3   58.00 
4   41.00 

LeftoverPayment 
--------------- 
0    

Toute la valeur doit de 0 été et @paymentAmmount à la fin devrait également être 0. Ce qui ne va pas que fait que les valeurs ne sont pas appliquées correctement?


P.S. Je sais comment fix it, juste casser une requête pour les 3 requêtes suivantes, mais je voulais le faire en une seule requête, donc je ne l'ai pas besoin d'autant de recherches sur la table réelle

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 

Je voulais juste savoir pourquoi ce que je fais actuellement ne fonctionne pas.

+0

pourquoi utiliser un curseur? (qui manque le close et libère, btw) –

+0

@MitchWheat 1) les curseurs déclarés locaux n'ont pas besoin d'être fermés/désalloués: P 2) il s'agit d'une recréation simplifiée d'une requête beaucoup plus grande. J'ai besoin de rapprocher les paiements appliquant le paiement à la charge la plus ancienne en premier. –

+0

"les curseurs déclarés locaux n'ont pas besoin d'être fermés/désalloués" - avez-vous une référence pour cela? –

Répondre

1
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 
declare @paymentAmmountbuf 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 
     select @[email protected] 

     update @tmp 
      set UNPAID = case when @paymentAmmountbuf > UNPAID then 0 else UNPAID - @paymentAmmountbuf 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 
+0

Sournois! Je pense que cela pourrait être ma solution mais j'attendrai un peu pour voir si d'autres réponses se présentent. –

Questions connexes