2016-08-25 3 views
0

私は最終的に私のクエリの更新コードを完了しました Nested Cursor based update (私はちょうど私が別のテーブルにすべての変数を挿入したので、数字を修正するために結合+合体を残しました。更新ステートメントは、すべての更新ステートメントを削除してもカーソルを破棄するため、カーソル宣言に残っています)ネストされたカーソルをセットベースのアプローチに変換しますか?

ただし、コピーしてSSRSに貼り付けようとすると、カーソルに使用されているすべての変数が考慮されます"宣言されていない"

変数名 '@TranLoan'は既に宣言されています。変数名は、クエリ・バッチまたはストアド・プロシージャ内で一意である必要があります。

スカラー変数 "@TranPrin"を宣言する必要があります。

スカラー変数 "@DelqPrin"を宣言する必要があります。

[各変数がコードに現れる時間ごとに一度、これが同じ変数に対して継続し、両方のカーソルのすべての変数が同じエラーでリストにある] 事が@TranLoanで一度だけ宣言されています。添付されているコードの簡略化されたバージョンです(基本的に3つではなく、1つのローンにつき1つの金額で実行します) 誰かが集合ベースのアプローチを思いつくことができたら、私はこれらのカーソルを完全に捨てることができます。テーブルのセットアップの

表セットアップ

IF OBJECT_ID('tempdb.dbo.#DQ') IS NOT NULL DROP TABLE #DQ 
IF OBJECT_ID('tempdb.dbo.#DelqAmts') IS NOT NULL DROP TABLE #DelqAmts 
IF OBJECT_ID('tempdb.dbo.#Tran') IS NOT NULL DROP TABLE #Tran 
--IF OBJECT_ID('tempdb.dbo.#DelqAmts') IS NOT NULL DROP TABLE #DelqAmts 
CREATE TABLE #DQ 
([LoanNumber] int, [Amount] money, [PaidToDate] datetime); 
CREATE TABLE #DelqAmts 
([LoanNumber] int, [Amount] money, [PaidToDate] datetime); 
INSERT INTO #DQ 
([LoanNumber], [Amount], [PaidToDate]) 
VALUES 
(56452, 739.97, '2015-09-01 00:00:00'), 
(56452, 738.35, '2015-10-01 00:00:00'), 
(56452, 736.72, '2015-11-01 00:00:00'), 
(56452, 735.08, '2015-12-01 00:00:00'), 
(56452, 733.44, '2016-01-01 00:00:00'), 
(56452, 731.79, '2016-02-01 00:00:00'), 
(56452, 730.13, '2016-03-01 00:00:00'), 
(56452, 728.46, '2016-04-01 00:00:00'), 
(56452, 726.79, '2016-05-01 00:00:00'), 
(56452, 725.1, '2016-06-01 00:00:00'), 
(78553, 436.43, '2016-02-01 00:00:00'), 
(78553, 435.72, '2016-03-01 00:00:00'), 
(78553, 435, '2016-04-01 00:00:00'), 
(78553, 434.28, '2016-05-01 00:00:00'), 
(78553, 433.55, '2016-06-01 00:00:00'); 
CREATE TABLE #Tran 
([LoanNumber] int, [TranAmount] money); 
INSERT INTO #Tran 
(LoanNumber, TranAmount) 
VALUES 
(56452, 833.97), 
(78553, 1653.17); 

エンド

declare @Col money = 0 -- Total Collected principal 
, @TranLoan varchar(10) --Loan number for current transaction 
, @TranPrin money = 0 -- Tran loan collected principal 
, @POPrin money = 0 -- Tran loan collected principal 
, @TranCursor as CURSOR 
, @DelqLoan varchar(10) 
, @DelqPrin money -- Current loan collected principal 
, @DelqPTD date 
, @DelqCursor as CURSOR 


set @TranCursor = Cursor FORWARD_ONLY 
For Select LoanNumber, [TranAmount] 
From #Tran 

Open @TranCursor; 
Fetch next from @TranCursor into @TranLoan, @TranPrin 

set @Col = 0 

while (@@Fetch_status = 0) 
Begin 

select @TranLoan as Loan, @TranPrin as TPrin 
set @DelqCursor = CURSOR FORWARD_ONLY 
FOR select LoanNumber,Amount ,PaidToDate 
from #DQ 
    where LoanNumber = @TranLoan 
    Order by PaidToDate Asc; 
-- For update OF Amount; 
    Open @DelqCursor 

     Fetch next from @DelqCursor into @DelqLoan, @DelqPrin,@DelqPTD 

     while (@@Fetch_status = 0) 

     Begin 
      IF @TranPrin = 0 
      SET @DelqPrin = 0 
     End 

     IF @TranPrin > 0 AND @TranPrin < @DelqPrin 
     BEGIN 
      SET @Col = @Col + @TranPrin 
      SET @DelqPrin = @TranPrin 
     --  select @TranLoan as Loan, @TranPrin as TPrin, @DelqPrin as DPrin, @DelqPTD as PTD, @Col as Col 
       SET @TranPrin = 0 
     END 

     IF @TranPrin >0 AND @TranPrin > @DelqPrin 
     BEGIN 
      SET @TranPrin = @TranPrin - @DelqPrin 
      SET @Col = @Col + @DelqPrin 
     END 

     Insert into #DelqAmts values (@DelqLoan, @DelqPrin, @DelqPTD) 
    Fetch next from @DelqCursor into @DelqLoan, @DelqPrin,@DelqPTD 
    End 

    Close @DelqCursor-- Finished with delinquent data for this loan. We close the cursor 
Fetch next from @TranCursor into @TranLoan, @TranPrin 
End 

Close @TranCursor 
deallocate @DelqCursor 
deallocate @TranCursor 

select * from #delqAmts -- This is a simplification of what I need out of this code block and isn't the end result of the report 

残りのコードが含まれていないので、変数は、この時点の後に使用されていません。

+0

この入れ子になったカーソルのアプローチを本当にゴミ箱に入れて、代わりにセットベースのアプローチにする必要があります。この全体を置き換えるために2つ以上の更新ステートメントを実行する必要があることを示唆するものはここにはありません。 –

+0

各ローンの延滞ラインを日付に基づいて個別にループして、その日付までの稼働合計を計算し、取引金額を引いた金額を引く必要があります。 – xenapan

+0

例を読んでください:毎月200元の3ヶ月の延滞、取引額は元本額500、最初の2つは残っており、3番目の値は100に減額されて取引金額合計に一致します – xenapan

答えて

0

これ以上のドキュメントやローリングサムをどのように見ていたら、これはもっと簡単になりました。ここでは最終的なクエリがあります(テーブルの設定を除いて)

select LoanNumber, PaidToDate, PrincipalCollected, 

    SumPrin, DelqPrin, 
    case when SumPrin <= PrincipalCollected then DelqPrin 
    When PrincipalCollected between SumPrin-DelqPrin and SumPrin then PrincipalCollected- (SumPrin-DelqPrin) 
     when SumPrin > PrincipalCollected then 0 
     end as ColPrin, 
    InterestCollected, SumInt, DelqInt, 
    case when SumInt <= InterestCollected then DelqInt 
     When InterestCollected between SumInt-DelqInt and SumInt then InterestCollected- (SumInt-DelqInt) 
     when SumInt > InterestCollected then 0 
     end as ColInt, 
    ServiceFee, SumServ, DelqServFee, 
     case when SumServ <= ServiceFee then DelqServFee 
     When ServiceFee between SumServ-DelqServFee and SumServ then ServiceFee- (SumServ-DelqServFee) 
     when SumServ > ServiceFee then 0 
     end as ColServ 
     from (
SELECT tf.LoanNumber,tf.PrincipalCollected,InterestCollected, ServiceFee, 
dq.PaidToDate, 
DelqPrin, SUM(DelqPrin) OVER (Partition by dq.LoanNumber ORDER BY dq.PaidToDate) as SumPrin, 
DelqInt, SUM(DelqInt) OVER (Partition by dq.LoanNumber ORDER BY dq.PaidToDate) as SumInt, 
DelqServFee, SUM(DelqServFee) OVER (Partition by dq.LoanNumber ORDER BY dq.PaidToDate) as SumServ 

FROM #tran tf 
left join #dq dq on tf.LoanNumber = dq.LoanNumber 
) as A 
ORDER BY LOanNumber, PaidToDate 

セットベースの方法ほどずっと簡単です。サブクエリとしてローリングサムを実行し、必要な数を得るために数式を適用するだけでした。