-1

我正在使用包存储过程接受数组(表)参数,您可以看到相关问题需要包示例中的 Oracle 存储过程接受数组(表)参数。创建 storeprocedur 时没有错误,但是当我调用它时,那里是一些错误。这是什么是存储过程:

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;
/

等待帮助!请。

4

1 回答 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
于 2012-07-11T18:59:01.687 回答