发布您遇到的错误总是有帮助的。这样我们就不用猜测了。我可以看到的错误...
首先,您不需要在包中声明类型。您已经在定义 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