我正在开发一个接受数组(表)参数的包存储过程,您可以看到相关问题需要包示例中接受数组(表)参数的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;
/
等待您的帮助,请
发布您遇到的错误总是有帮助的。这样我们就不用猜测了。我看到的错误...
首先,您不需要在包中声明类型。您已经定义了 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