使用Cursor定义游标

时间:2018-05-03 02:34:58

标签: oracle plsql

我目前正在尝试从财务数据库中获取每笔费用的总欠款和总额。详细说来,说我有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 

然而,当我运行它时,它显示每笔费用的欠款和付款为空。关于我的代码出错的任何想法?

2 个答案:

答案 0 :(得分:1)

您可以在单个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

此代码使用外部联接,允许在提交详细信息之前监控费用,并可选择处理信用卡付款。显然,我不得不对您的表结构和数据做出一些假设,因此您可能需要调整此代码以使其按您的需要工作。

这是a SQL Fiddle

此外,您应该避免使用自然连接。是的ANSI SQL标准支持它们,是的,知道它们存在是有用的。但在现实生活中,他们只是一个等待发生的错误。

答案 1 :(得分:0)

在你的代码中,打开光标的序列有一个小错误,我已经纠正了所有这些错误。光标“CurrentNum”是其他光标的驱动程序光标,因此,您必须在驱动程序光标的循环内打开另外两个光标。以下是正确的,有希望检查,它解决了你的目的。

develop