使用光标输入时程序包未执行

时间:2019-06-07 05:00:22

标签: sql oracle plsql

我已经从现有过程创建了一个Package,该过程仅给出准确的输出,但是在创建软件包时没有错误,但是没有显示我传递给游标的输入文件 < / p>


------------------包装如下------------------------- < / h2>
SET SERVEROUTPUT ON;
CREATE OR REPLACE PACKAGE user.report AS
    PROCEDURE distribution (
        code_in   IN             user.test.schm_code%TYPE,
        fromdate       IN             DATE,
        todate         IN             DATE
    );

END report;
/
-------------------------------------------------
----------------Package Body---------------------
-------------------------------------------------

CREATE OR REPLACE PACKAGE BODY user.report as
----------------------------------------------
----------VARIABLE DECLARATION----------------
----------------------------------------------

    code_in             user.test.code%TYPE;
    fromdate                 DATE;
    todate                   DATE;
    v_code              user.test.code%TYPE;    
    v_count                 number;
    v_code          user.test.acct_crncy_code%TYPE;
    v_amount        number(17,4);
-----------------------------------------------
---------------CURSOR DECLARATION--------------
-----------------------------------------------


CURSOR td_data IS
    ( SELECT
        test.code,
        COUNT(test.code) AS count,
        test.crncy
    FROM
        user.table1
        JOIN user.test ON test.id = table1.id
    WHERE
        user.test.opendate BETWEEN TO_DATE(fromdate, 'dd-mm-yyyy') AND TO_DATE(todate, 'dd-mm-yyyy')
        and
        user.test.code = code_in
    GROUP BY
        test.code,test.crncy
    );

------------------------PROCEDURE CREATION-----------------------    
PROCEDURE distribution 
(
    code_in   IN             user.test.code%TYPE,
    fromdate       IN          DATE,
    todate         IN          DATE
)
AS
BEGIN
    dbms_output.put_line('code'||'    '||'COUNT'||'       '||'TOTAL');
    OPEN td_data;
    LOOP
        FETCH td_data INTO v_code,v_count,v_code,v_amount;
        EXIT WHEN td_data%notfound;
        dbms_output.put_line(v_code
                             || '             '
                             ||v_count
                             || '                '
                             ||v_code
                             ||' '
                             ||v_amount
                             );

    END LOOP;

    CLOSE td_data;
EXCEPTION
    WHEN OTHERS THEN
        dbms_output.put_line(SQLERRM);
END distribution;
END report;
/
BEGIN
user.report.distribution('x1fsr','01-02-2016','01-07-2020');
END;
/

alter session set nls_date_format='dd-mm-yyyy'; 

我尝试创建没有光标正常工作的程序包 我尝试在没有用户输入正常的情况下创建游标,但在用户输入下无法正常工作

2 个答案:

答案 0 :(得分:2)

您使用的变量未初始化,因此游标未获取任何内容。这是因为您在全局范围内(整个包主体)声明了它(以及一堆变量),而不是局部地声明了(对于过程,当您将参数传递给过程并且从未传递任何参数时)如果需要,请创建一个参数化的游标)。

此外,您已经两次声明V_CODE;为什么?

无论如何:我建议您这样做:

  • 使用游标FOR循环,因为它易于维护(您不必打开,获取,退出,关闭-Oracle会为您完成此操作)
  • 不声明任何其他变量-使用隐式游标变量
  • 删除这样的异常处理程序,因为您没有处理任何事情,它根本没有好处。如果您是从某个前端应用程序(例如Apex或Forms)中调用该过程的,而发生了一些事情(“ others”,是吗?),您将看不到任何内容,因为DBMS_OUTPUT.PUT_LINE在这里不起作用
  • 由于fromdatetodateDATE,因此无需TO_DATE

好,你去:

CREATE OR REPLACE PACKAGE BODY USER.report
AS
   PROCEDURE distribution (code_in   IN USER.test.code%TYPE,
                           fromdate  IN DATE,
                           todate    IN DATE)
   AS
   BEGIN
      DBMS_OUTPUT.put_line (
         'code' || '    ' || 'COUNT' || '       ' || 'TOTAL');

      FOR cur_r
         IN (  SELECT test.code, COUNT (test.code) AS COUNT, test.crncy
                 FROM USER.table1 JOIN USER.test ON test.id = table1.id
                WHERE     USER.test.opendate BETWEEN fromdate AND todate
                      AND USER.test.code = code_in
             GROUP BY test.code, test.crncy)
      LOOP
         DBMS_OUTPUT.put_line (
               v_code
            || '             '
            || cur_r.code
            || '                '
            || cur_r.COUNT
            || ' '
            || cur_r.crncy);
      END LOOP;
   END distribution;
END report;

答案 1 :(得分:2)

您已经创建了一个接受参数(parameterized cursors)的游标,但是忘记将参数传递给游标。无法在游标查询之外引用游标参数。

您也可以通过在光标内部简单地传递声明的参数来解决

SET SERVEROUTPUT ON;
alter session set nls_date_format='dd-mm-yyyy';  
CREATE OR REPLACE PACKAGE user.report AS
    PROCEDURE distribution (
        code_in   IN             user.test.schm_code%TYPE,
        fromdate       IN             DATE,
        todate         IN             DATE
    );

END report;
/

包装体

CREATE OR REPLACE PACKAGE BODY user.report as
----------------------------------------------
----------VARIABLE DECLARATION----------------
----------------------------------------------

    code_in             user.test.code%TYPE;
    fromdate                 DATE;
    todate                   DATE;
    v_code              user.test.code%TYPE;    
    v_count                 number;
    v_code          user.test.acct_crncy_code%TYPE;
    v_amount        number(17,4);
-----------------------------------------------
---------------CURSOR DECLARATION--------------
-----------------------------------------------


CURSOR td_data(code_in user.test.code%TYPE,fromdate DATE ,todate DATE )IS
    ( SELECT
        test.code,
        COUNT(test.code) AS count,
        test.crncy
    FROM
        user.table1
        JOIN user.test ON test.id = table1.id
    WHERE
        user.test.opendate BETWEEN TO_DATE(fromdate, 'dd-mm-yyyy') AND TO_DATE(todate, 'dd-mm-yyyy')
        and
        user.test.code = code_in
    GROUP BY
        test.code,test.crncy
    );

------------------------PROCEDURE CREATION-----------------------    
PROCEDURE distribution 
(
    code_in   IN             user.test.code%TYPE,
    fromdate       IN          DATE,
    todate         IN          DATE
)
AS
BEGIN
    dbms_output.put_line('code'||'    '||'COUNT'||'       '||'TOTAL');
    OPEN td_data;
    LOOP
        FETCH td_data INTO v_code,v_count,v_code,v_amount;
        EXIT WHEN td_data%notfound;
        dbms_output.put_line(v_code
                             || '             '
                             ||v_count
                             || '                '
                             ||v_code
                             ||' '
                             ||v_amount
                             );

    END LOOP;

    CLOSE td_data;
EXCEPTION
    WHEN OTHERS THEN
        dbms_output.put_line(SQLERRM);
END distribution;
END report;
/

打包执行

BEGIN
user.report.distribution('x1fsr','01-02-2016','01-07-2020');
END;
/