簡體   English   中英

使用游標定義游標

[英]Using Cursor to define cursor

我目前正在嘗試從財務數據庫中訪問所有費用的欠款總額和總付款額。 詳細說,我有5筆費用。 每個費用中都有許多項目,可以將其總計加起來以得到其費用總額。 費用還具有已支付的金額。 我需要在表中顯示這些數字(所欠和已付)是否等於每種費用。 我有以下內容:

SET ECHO OFF
SET VERIFY OFF
SET SERVEROUTPUT ON

DECLARE
    paid NUMBER;
    owed NUMBER;
    ExpNumber NUMBER;

    CURSOR CurrentNum IS
    SELECT ExpNum FROM ExpMast;
    CURSOR walkthrough IS

        SELECT SUM(Amt)
        FROM ExpDet WHERE ExpNum = ExpNumber;

    CURSOR wlkthr IS 
        SELECT SUM(CashAmt+Amt) FROM
        ExpMast NATURAL JOIN ExpByCC WHERE ExpNum = ExpNumber;

BEGIN
    OPEN walkthrough;
    OPEN wlkthr;
    OPEN CurrentNum;
    LOOP
        FETCH walkthrough INTO owed;
        FETCH wlkthr INTO paid;
        FETCH CurrentNum INTO ExpNumber;
        EXIT WHEN CurrentNum%NOTFOUND;  
        DBMS_OUTPUT.PUT_LINE('Calculating expenses for Exp: ' || ExpNumber);
            IF paid = owed THEN
                DBMS_OUTPUT.PUT_LINE('All Expenses paid. Total: ' || owed);

            ELSE
                DBMS_OUTPUT.PUT_LINE('Amount Paid: ' || paid);
                DBMS_OUTPUT.PUT_LINE('Total Owed: ' || owed);
                DBMS_OUTPUT.PUT_LINE('Difference: ' || (owed-paid));
            END IF;              
    END LOOP;
    CLOSE walkthrough;
    CLOSE wlkthr;
    CLOSE CurrentNum;
END;
/
SET VERIFY ON
SET ECHO ON 

但是,當我運行它時,它顯示每筆費用的欠款和已付款為空。 關於我的代碼哪里出錯的任何想法?

您可以在單個SQL查詢中實現

select em.ExpNum 
          , nvl(ed.owed, 0) as owed
          , nvl(ecc.cc_paid, 0) + em.CashAmt as paid
          , nvl(ed.owed, 0) - (nvl(ecc.cc_paid, 0) + em.CashAmt) as diff
from ExpMast em
        left join ( select ExpNum, sum(Amt) as owed 
                    from ExpDet 
                    group by ExpNum ) ed
            on ed.ExpNum  = em.ExpNum  
        left join  ( select ExpNum, sum(Amt) as cc_paid 
                    from ExpByCC 
                    group by ExpNum ) ecc
            on ecc.ExpNum  = em.ExpNum    
order by em.ExpNum

此代碼使用外部聯接,該外部聯接允許在提交詳細信息之前監視費用,並可以選擇處理信用卡付款。 顯然,我不得不對您的表結構和數據進行一些假設,因此您可能需要調整此代碼以使其按需工作。

這是一個SQL Fiddle


另外,您應該避免使用自然聯接。 是的,ANSI SQL標准支持它們,是的,知道它們的存在很有用。 但是在現實生活中,它們只是一個等待發生的錯誤。

在您的代碼中,打開游標的順序存在一個小錯誤,我已更正了所有這些錯誤。 游標“ CurrentNum”是其他游標的驅動程序游標,因此,您必須在驅動程序游標的循環內打開另外兩個游標。 下面是正確的一個,希望可以檢查出來,它解決了您的目的。

DECLARE
    paid NUMBER;
    owed NUMBER;
    ExpNumber NUMBER;

CURSOR CurrentNum IS
    SELECT ExpNum FROM ExpMast;

    CURSOR walkthrough IS
        SELECT SUM(Amt)
        FROM ExpDet WHERE ExpNum = ExpNumber;

    CURSOR wlkthr IS
        SELECT SUM(CashAmt+Amt) FROM
        ExpMast NATURAL JOIN ExpByCC WHERE ExpNum = ExpNumber;
BEGIN
    OPEN CurrentNum;
    LOOP
        FETCH CurrentNum INTO ExpNumber;
        EXIT WHEN CurrentNum%NOTFOUND;
        DBMS_OUTPUT.PUT_LINE('Calculating expenses for Exp: ' || ExpNumber);

        OPEN walkthrough;
        FETCH walkthrough INTO owed;

        OPEN wlkthr;
        FETCH wlkthr INTO paid;

        IF paid = owed THEN
                DBMS_OUTPUT.PUT_LINE('All Expenses paid. Total: ' || owed);

            ELSE
                DBMS_OUTPUT.PUT_LINE('Amount Paid: ' || paid);
                DBMS_OUTPUT.PUT_LINE('Total Owed: ' || owed);
                DBMS_OUTPUT.PUT_LINE('Difference: ' || (owed-paid));
            END IF;
        CLOSE walkthrough;
        CLOSE wlkthr;
    END LOOP;
    CLOSE CurrentNum;
END;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM