将Java数组传入存储过程

时间:2017-01-25 14:57:35

标签: arrays oracle stored-procedures plsql

我试图将java数组传递给我的存储过程并使用数组中的值更新记录。目前,当我尝试执行并测试存储过程时,我遇到了

  

错误:ORA-06531:引用未初始化的集合。

任何人都可以向我推进正确的方向或帮我清理我的代码。以下是身体后面的包装规格。

CREATE OR REPLACE package AOMS.test_array1 as

type t1 is record (
s1 varchar2(1),
i_part_no varchar2(20),
i_itc varchar2(20),
s2 varchar2(1),
l_part_no varchar2(20));

type tab1 is table of t1 ;

tab2 tab1;

这是身体。

CREATE OR REPLACE PACKAGE BODY AOMS.TEST_ARRAY1 AS 

I_ARRAY varchar2(1000);

PROCEDURE test_array2(i_array IN tab2%TYPE) AS

  l_s1 VARCHAR2(50);
  l_part_no1 VARCHAR2(50);
  l_itc varchar2(50);
  l_s2 varchar2(50);
  l_part_no2  varchar2(50);

BEGIN
   FOR x IN i_array.first .. i_array.last
   LOOP
  l_s1 := i_array(x).s1;
  l_part_no1 := i_array(x).i_part_no;
  l_itc := i_array(x).i_itc;
  l_s2  := i_array(x).s2;
  l_part_no2  := i_array(x).l_part_no;

  UPDATE replacement_parts
   SET frst_src = l_s1,
   frst_part_no = l_part_no1,
   ITC = l_itc,
   last_src = l_s2,
   last_part_no = l_part_no2


   WHERE    
     frst_src = 'P'
  AND frst_part_no = '96424447            ';
 COMMIT;
 END LOOP;
 END test_array2;
 END test_array1;
 /

我正在使用Toad所以当我调用该程序时,我只需右键单击并执行并输入我的参数。这是我尝试执行时生成的匿名块代码。

DECLARE 
  I_ARRAY AOMS.TEST_ARRAY1.tab2%type;

BEGIN 
  -- I_ARRAY := NULL; Modify the code to initialize this parameter

  AOMS.TEST_ARRAY1.TEST_ARRAY2 ( I_ARRAY );
  COMMIT; 
END;

1 个答案:

答案 0 :(得分:1)

您在程序包和过程调用中都存在一些问题。 这应该有效:

CREATE OR REPLACE PACKAGE test_array1 AS
    TYPE t1 IS RECORD
    (
        s1                                      VARCHAR2(1),
        i_part_no                               VARCHAR2(20),
        i_itc                                   VARCHAR2(20),
        s2                                      VARCHAR2(1),
        l_part_no                               VARCHAR2(20)
    );

    TYPE tab1 IS TABLE OF t1;

    tab2                                    tab1;

    PROCEDURE test_array2(i_array IN tab1);
END test_array1;
CREATE OR REPLACE PACKAGE BODY TEST_ARRAY1 AS
    I_ARRAY                                 VARCHAR2(1000);

    PROCEDURE test_array2(i_array IN tab1) IS
        l_s1                                    VARCHAR2(50);
        l_part_no1                              VARCHAR2(50);
        l_itc                                   VARCHAR2(50);
        l_s2                                    VARCHAR2(50);
        l_part_no2                              VARCHAR2(50);
    BEGIN
        IF i_array.COUNT > 0
        THEN
            FOR x IN i_array.FIRST .. i_array.LAST
            LOOP
                l_s1          := i_array(x).s1;
                l_part_no1    := i_array(x).i_part_no;
                l_itc         := i_array(x).i_itc;
                l_s2          := i_array(x).s2;
                l_part_no2    := i_array(x).l_part_no;

                UPDATE replacement_parts
                   SET frst_src        = l_s1,
                       frst_part_no    = l_part_no1,
                       ITC             = l_itc,
                       last_src        = l_s2,
                       last_part_no    = l_part_no2
                 WHERE     frst_src = 'P'
                       AND frst_part_no = '96424447            ';

                COMMIT;
            END LOOP;
        END IF;
    END test_array2;
END test_array1;
/

电话:

DECLARE 
  I_ARRAY TEST_ARRAY1.tab1;

BEGIN 
  I_ARRAY :=  TEST_ARRAY1.tab1();

  TEST_ARRAY1.TEST_ARRAY2 ( I_ARRAY );
  COMMIT; 
END;

我所做的改变:

  • 您在包中定义了一个类型,然后使用类似variable%type的内容来声明该过程,而您只需使用该类型。
  • 包中的
  • ,在扫描集合时,最好在尝试使用collection.first之前检查集合是否具有值。尝试访问空集合上的.first可能会导致出现问题。
  • 在调用者中,您需要按照我展示的方式初始化集合以避免您遇到的错误

顺便说一句,你应该更好地尝试为变量,类型,程序,包使用更多解释性名称,以避免不同对象之间的混淆。

另一件事:你在循环中有一个commit;这意味着,撇开表演,如果第一个,比方说3个记录被更新,然后你有错误,你提交3个更新;这真的是你需要的吗?此外,这样调用方中的commit也是无用的。