Oracle封装存储过程,不知道如何调试(用代码)

问题描述 投票:0回答:1

我正在开发一个接受数组(表)参数的包存储过程,您可以看到相关问题需要包示例中接受数组(表)参数的Oracle存储过程

创建存储过程时没有错误,但是当我调用它时,出现一些错误。

这就是存储过程的样子:

CREATE OR REPLACE TYPE t_table IS TABLE of VARCHAR2(255);
    /
    CREATE OR REPLACE PACKAGE simon_pkg IS
        TYPE t_table IS TABLE of VARCHAR2(255);
        TYPE c_cursor IS ref CURSOR;
        PROCEDURE f (t_input in t_table,c_out out c_cursor);
    END;
    /
    CREATE OR REPLACE PACKAGE BODY simon_pkg IS
        PROCEDURE f (t_input in t_table,c_out out c_cursor) IS
            v_cursor c_cursor;
        BEGIN
            OPEN v_cursor FOR
                SELECT last_name
                FROM employees
                WHERE last_name IN
                    (SELECT * FROM TABLE(t_input));
            c_out := v_cursor;
        END f;
    END;
    /

这就是我调用它时正在做的事情:

DECLARE
    TYPE c_cur IS REF CURSOR;
    c_result c_cur;
    m_table t_table := t_table();
BEGIN
    m_table.EXTEND(2);
    m_table(1) := 'Urman';
    m_table(2) := 'Vargas';
    simon_pkg.f(m_table,c_result);
    SELECT * FROM TABLE(c_result);
END;
/

等待您的帮助,请

arrays oracle stored-procedures
1个回答
2
投票

发布您遇到的错误总是有帮助的。这样我们就不用猜测了。我看到的错误...

首先,您不需要在包中声明类型。您已经定义了 SQL 类型

CREATE OR REPLACE TYPE t_table IS TABLE of VARCHAR2(255);
/

您的包声明不应声明具有相同名称的单独 PL/SQL 类型。这只会让你的生活更具挑战性,因为你必须弄清楚对

t_table
的任何给定引用正在使用两种类型中的哪一种。您的包声明也不需要声明弱引用游标的类型——Oracle 已经提供了
sys_refcursor
类型。因此,您的包装规格只需

CREATE OR REPLACE PACKAGE simon_pkg 
IS
    PROCEDURE f (t_input in t_table,
                 c_out out sys_refcursor);
END;
/

这意味着你的包体可以是

 CREATE OR REPLACE PACKAGE BODY simon_pkg IS
    PROCEDURE f (t_input in t_table,
                 c_out  out sys_refcursor) 
    IS
    BEGIN
        OPEN c_out FOR
            SELECT last_name
            FROM employees
            WHERE last_name IN
                (SELECT * FROM TABLE(t_input));
    END f;
END;

根据您想要完成的任务,可以通过几种不同的方式来调用该过程。您可以编写迭代光标并将输出写入

dbms_output
缓冲区的代码(假设您使用的任何工具都知道如何从缓冲区读取以显示输出)。

DECLARE
    c_result sys_refcursor;
    m_table t_table := t_table();
    l_last_name varchar2(100);
BEGIN
    m_table.EXTEND(2);
    m_table(1) := 'Urman';
    m_table(2) := 'Vargas';
    simon_pkg.f(m_table,c_result);

    LOOP
      FETCH c_result INTO l_last_name;
      EXIT WHEN c_result%notfound;
      dbms_output.put_line( l_last_name );
    END LOOP;
    CLOSE c_result;
END;
/

如果您使用 SQL*Plus(或其他实现 SQL*Plus 变量的东西)

VARIABLE rc refcursor;

DECLARE
    m_table t_table := t_table();
BEGIN
    m_table.EXTEND(2);
    m_table(1) := 'Urman';
    m_table(2) := 'Vargas';
    simon_pkg.f(m_table,:rc);
END;

PRINT rc;

假设您使用 SQL*Plus 和

HR
模式,您可以看到第一个选项的输出

SQL> CREATE OR REPLACE TYPE t_table IS TABLE of VARCHAR2(255);
  2  /

Type created.

SQL> CREATE OR REPLACE PACKAGE simon_pkg
  2  IS
  3      PROCEDURE f (t_input in t_table,
  4                   c_out out sys_refcursor);
  5  END;
  6  /

Package created.

SQL>  CREATE OR REPLACE PACKAGE BODY simon_pkg IS
  2      PROCEDURE f (t_input in t_table,
  3                   c_out  out sys_refcursor)
  4      IS
  5      BEGIN
  6          OPEN c_out FOR
  7              SELECT last_name
  8              FROM employees
  9              WHERE last_name IN
 10                  (SELECT * FROM TABLE(t_input));
 11      END f;
 12  END;
 13  /

Package body created.

SQL> set serveroutput on;
SQL> DECLARE
  2      c_result sys_refcursor;
  3      m_table t_table := t_table();
  4      l_last_name varchar2(100);
  5  BEGIN
  6      m_table.EXTEND(2);
  7      m_table(1) := 'Urman';
  8      m_table(2) := 'Vargas';
  9      simon_pkg.f(m_table,c_result);
 10
 11      LOOP
 12        FETCH c_result INTO l_last_name;
 13        EXIT WHEN c_result%notfound;
 14        dbms_output.put_line( l_last_name );
 15      END LOOP;
 16      CLOSE c_result;
 17  END;
 18  /
Urman
Vargas

PL/SQL procedure successfully completed.

第二个选项的输出

SQL> VARIABLE rc refcursor;
SQL> DECLARE
  2      m_table t_table := t_table();
  3  BEGIN
  4      m_table.EXTEND(2);
  5      m_table(1) := 'Urman';
  6      m_table(2) := 'Vargas';
  7      simon_pkg.f(m_table,:rc);
  8  END;
  9  /

PL/SQL procedure successfully completed.

SQL> PRINT rc;

LAST_NAME
-------------------------
Urman
Vargas
© www.soinside.com 2019 - 2024. All rights reserved.