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

发布于 2024-09-02 10:26:42 字数 549 浏览 3 评论 0原文

我正在尝试将 (varchar) 数据数组传递到 Oracle 过程中。 Oracle 过程可以从 SQL*Plus 或另一个 PL/SQL 过程调用,如下所示:

BEGIN
 pr_perform_task('1','2','3','4');
END;

pr_perform_task 将读取每个输入参数并执行任务。

我不确定如何才能实现这一目标。我的第一个想法是使用 varray 类型的输入参数,但当过程定义时,我收到 Error: PLS-00201:identifier 'VARRAY' must be statements 错误看起来像这样:

CREATE OR REPLACE PROCEDURE PR_DELETE_RECORD_VARRAY(P_ID VARRAY) IS

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

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

I'm trying to pass an array of (varchar) data into an Oracle procedure. The Oracle procedure would be either called from SQL*Plus or from another PL/SQL procedure like so:

BEGIN
 pr_perform_task('1','2','3','4');
END;

pr_perform_task will read each of the input parameters and perform the tasks.

I'm not sure as to how I can achieve this. My first thought was to use an input parameter of type varray but I'm getting Error: PLS-00201: identifier 'VARRAY' must be declared error, when the procedure definiton looks like this:

CREATE OR REPLACE PROCEDURE PR_DELETE_RECORD_VARRAY(P_ID VARRAY) IS

To summarize, how can I pass the data as an array, let the SP loop through each of the parameters and perform the task ?

I'm using Oracle 10gR2 as my database.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

天赋异禀 2024-09-09 10:26:42

这是一种方法:

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 类型(不能是关联数组) )并要求定义一个所有人都可以看到的包,以便所有人都可以使用它定义的 TYPE。

This is one way to do it:

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

To expand on my comment to @dcp's answer, here's how you could implement the solution proposed there if you wanted to use an associative array:

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> 

This trades creating a standalone Oracle TYPE (which cannot be an associative array) with requiring the definition of a package that can be seen by all in order that the TYPE it defines there can be used by all.

逆流 2024-09-09 10:26:42

如果参数的类型全部相同(例如 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;
/

If the types of the parameters are all the same (varchar2 for example), you can have a package like this which will do the following:

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;

Then, to call it you'd need to set up the array and pass it:

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;
/
薄荷→糖丶微凉 2024-09-09 10:26:42

您可能喜欢:

  1. 创建表类型。用户执行以下命令

    创建或替换类型 StringListType AS TABLE OF VARCHAR2(1024);
    
  2. 创建过程:

    创建或替换过程 PR_DELETE_RECORD_VARRAY(
        pList IN 字符串列表类型
    ) 作为
    开始
    
        FOR i IN 1..pList.COUNT 循环
            DBMS_OUTPUT.PUT_LINE('项目:' || pList(i));
          /*
           在这里写逻辑
         */
        结束循环;
    结尾;
    
  3. 调用过程:

    <前><代码>声明
    vList StringListType := StringListType('1', '2', '3');

    开始
    PR_DELETE_RECORD_VARRAY(pList => vList);
    结尾;
    /

You may user like:

  1. Create table types. user below command

    CREATE OR REPLACE TYPE StringListType AS TABLE OF VARCHAR2(1024);
    
  2. Create Procedure:

    CREATE OR REPLACE PROCEDURE PR_DELETE_RECORD_VARRAY(
        pList  IN StringListType
    ) AS
    BEGIN
    
        FOR i IN 1..pList.COUNT LOOP
            DBMS_OUTPUT.PUT_LINE('item: ' || pList(i));
          /*
           write logic here
         */
        END LOOP;
    END;
    
  3. Call the procedure:

    DECLARE
        vList StringListType := StringListType('1', '2', '3');
    
    BEGIN
        PR_DELETE_RECORD_VARRAY(pList => vList);
    END;
    /
    
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文