将数据数组作为输入参数传递给Oracle过程

将数据数组作为输入参数传递给Oracle过程,oracle,stored-procedures,plsql,Oracle,Stored Procedures,Plsql,我试图将(varchar)数据数组传递到Oracle过程中。Oracle过程可以从SQL*Plus调用,也可以从其他PL/SQL过程调用,如下所示: BEGIN pr_perform_task('1','2','3','4'); END; pr_perform_task将读取每个输入参数并执行任务 我不知道如何才能做到这一点。我的第一个想法是使用类型为varray的输入参数,但我得到了错误:PLS-00201:必须声明标识符“varray”,当过程定义如下所示: 创建或替换过程PR\u DE

我试图将(
varchar
)数据数组传递到Oracle过程中。Oracle过程可以从SQL*Plus调用,也可以从其他PL/SQL过程调用,如下所示:

BEGIN
 pr_perform_task('1','2','3','4');
END;
pr_perform_task
将读取每个输入参数并执行任务

我不知道如何才能做到这一点。我的第一个想法是使用类型为
varray
的输入参数,但我得到了
错误:PLS-00201:必须声明标识符“varray”,当过程定义如下所示:

创建或替换过程PR\u DELETE\u RECORD\u VARRAY(p\u ID VARRAY)是

总之,如何将数据作为数组传递,让SP循环遍历每个参数并执行任务


我正在使用Oracle 10gR2作为我的数据库。

如果参数的类型都是相同的(
varchar2
),您可以有这样一个包,它将执行以下操作:

CREATE OR REPLACE PACKAGE testuser.test_pkg IS

   TYPE assoc_array_varchar2_t IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER;

   PROCEDURE your_proc(p_parm IN assoc_array_varchar2_t);

END test_pkg;

CREATE OR REPLACE PACKAGE BODY testuser.test_pkg IS

   PROCEDURE your_proc(p_parm IN assoc_array_varchar2_t) AS
   BEGIN
      FOR i IN p_parm.first .. p_parm.last
      LOOP
         dbms_output.put_line(p_parm(i));
      END LOOP;

   END;

END test_pkg;
然后,要调用它,您需要设置数组并传递它:

DECLARE
  l_array testuser.test_pkg.assoc_array_varchar2_t;
BEGIN
  l_array(0) := 'hello';
  l_array(1) := 'there';  

  testuser.test_pkg.your_proc(l_array);
END;
/

这是一种方法:

SQL> set serveroutput on
SQL> CREATE OR REPLACE TYPE MyType AS VARRAY(200) OF VARCHAR2(50);
  2  /

Type created

SQL> CREATE OR REPLACE PROCEDURE testing (t_in MyType) IS
  2  BEGIN
  3    FOR i IN 1..t_in.count LOOP
  4      dbms_output.put_line(t_in(i));
  5    END LOOP;
  6  END;
  7  /

Procedure created

SQL> DECLARE
  2    v_t MyType;
  3  BEGIN
  4    v_t := MyType();
  5    v_t.EXTEND(10);
  6    v_t(1) := 'this is a test';
  7    v_t(2) := 'A second test line';
  8    testing(v_t);
  9  END;
 10  /

this is a test
A second test line
为了进一步阐述我对@dcp答案的评论,如果您想使用关联数组,下面介绍如何实现此处提出的解决方案:

SQL> CREATE OR REPLACE PACKAGE p IS
  2    TYPE p_type IS TABLE OF VARCHAR2(50) INDEX BY BINARY_INTEGER;
  3  
  4    PROCEDURE pp (inp p_type);
  5  END p;
  6  /

Package created
SQL> CREATE OR REPLACE PACKAGE BODY p IS
  2    PROCEDURE pp (inp p_type) IS
  3    BEGIN
  4      FOR i IN 1..inp.count LOOP
  5        dbms_output.put_line(inp(i));
  6      END LOOP;
  7    END pp;
  8  END p;
  9  /

Package body created
SQL> DECLARE
  2    v_t p.p_type;
  3  BEGIN
  4    v_t(1) := 'this is a test of p';
  5    v_t(2) := 'A second test line for p';
  6    p.pp(v_t);
  7  END;
  8  /

this is a test of p
A second test line for p

PL/SQL procedure successfully completed

SQL> 

这就需要创建一个独立的Oracle类型(不能是关联数组),同时需要定义一个所有人都能看到的包,以便所有人都能使用它在其中定义的类型。

您不能创建Oracle类型的关联数组。唯一可行的方法是在包中定义类型并以这种方式引用它。@DCookie-我的错,谢谢你指出错误。我已经更正了我的答案:)。有必要创建一个包吗?我想你问错了问题。除了少数罕见的情况外,您应该始终使用软件包,请参阅此处:很好的答案。我想知道是否有可能实现第一种方法的功能,但是对于
t\u中的元素数量是动态的(即,每次调用
测试
)都是不同的情况?似乎至少需要硬编码
MyType
的上限?这一限制能否以某种方式解除?@ggkmath,数组有多大并不重要,但在创建或更改类型时必须声明VARRAY上限。是否有其他解决方案可以适应这种动态大小,也许没有VARRAY?如果脱离主题,我可以启动一个新线程。使用答案的后半部分-将类型设置为PL/SQL关联数组,并在包规范中定义它。对于我来说,我必须使用以下v_t p.p_type=p.p_type()初始化表类型:;稍后调用v_t.extend(10)为10个元素创建空间。不知道为什么它与你和我所做的不同。B我已经创建了一个表类型,这是我们创建的类型