【问题标题】:newbie simple example using VARRAY with JDBC and PL/SQL stored procedure使用 VARRAY 和 JDBC 和 PL/SQL 存储过程的新手简单示例
【发布时间】:2012-03-22 02:55:08
【问题描述】:

我正在尝试创建一个简单的示例来了解如何通过基于 VARRAY 的 PL/SQL 存储过程将数据从 Java 程序存储到 Oracle 数据库 (11.2G),然后将数据从 Java 程序检索到 Oracle 数据库 (11.2G)。

我已尽力将 Java 程序放在一起,但可能会出现一两个错误。我还坚持如何编写 PL/SQL 代码来编写然后从数据库读取 VARRAY。任何意见,将不胜感激。

Java 程序:

// create example array
double[] myArray = new double[3];
myArray[0] = 1.1;
myArray[1] = 2.2;
myArray[2] = 3.3;
...
// setup call to stored procedure using SQL92 syntax
cs = conn.prepareCall( "{call my_sproc (?,?)}" );
// set IN parameters
cs.setString(1, myArray);
// set OUT parameters
cs.registerOutParameter(2, Types.ARRAY, "my_array");
// execute
cs.execute();
// retrieve array 
double[] returnedArray = new double[3];
returnedArray = cs.getArray(2);
...

PL/SQL 存储过程:

create or replace procedure my_sproc ( 
    input_array IN as VARRAY(3) of BINARY_FLOAT,
    output_array OUT as VARRAY(3) of BINARY_FLOAT )
as
begin

-- how to write input_array into any example table?

-- how to read input_array from example table and store in variable: output_array?

end my_sproc;

【问题讨论】:

    标签: java database plsql oracle11g


    【解决方案1】:

    在 PL/SQL 中使用 VARRAY 非常少见,因为您必须指定最大长度。使用基于嵌套表或关联数组的集合更为常见。

    如果你确实想使用基于 VARRAY 的集合,你可以这样做

    create type float_array
        is varray(3) of binary_float;
    /
    
    create table foo (
      col1 number
    );
    /
    
    create or replace procedure varray_proc( p_in_arr   in float_array,
                                             p_out_arr out float_array )
    as
    begin
      for i in 1 .. p_in_arr.count
      loop
        insert into foo( col1 )
          values( p_in_arr(i) );
      end loop;
      select col1*2
        bulk collect into p_out_arr
        from foo;
    end;
    /
    

    您可以从 PL/SQL 调用该过程

    SQL> declare
      2    l_in_arr  float_array := float_array( 1.1, 2.2, 3.3 );
      3    l_out_arr float_array;
      4  begin
      5    varray_proc( l_in_arr,
      6                 l_out_arr );
      7    for i in 1 .. l_out_arr.count
      8    loop
      9      dbms_output.put_line( l_out_arr(i) );
     10    end loop;
     11  end;
     12  /
    2.20000005E+000
    4.4000001E+000
    6.5999999E+000
    
    PL/SQL procedure successfully completed.
    

    更常见的是声明和使用嵌套表类型,它最终看起来与 VARRAY 代码几乎完全相同,只是没有长度限制

    create type float_nt
        is table of binary_float;
    
    create or replace procedure varray_proc( p_in_arr   in float_nt,
                                             p_out_arr out float_nt )
    as
    begin
      for i in 1 .. p_in_arr.count
      loop
        insert into foo( col1 )
          values( p_in_arr(i) );
      end loop;
      select col1*2
        bulk collect into p_out_arr
        from foo;
    end;
    /
    

    如果要存储数组元素的顺序

    create table bar (
      col1     number, 
      order_by number
    );
    
    create or replace procedure varray_proc( p_in_arr   in float_nt,
                                             p_out_arr out float_nt )
    as
    begin
      for i in 1 .. p_in_arr.count
      loop
        insert into bar( col1, order_by )
          values( p_in_arr(i), i );
      end loop;
      select col1*2
        bulk collect into p_out_arr
        from bar
       order by order_by;
    end;
    /
    

    【讨论】:

    • 谢谢贾斯汀,就我而言,我总是知道 Java 中数组的长度,而且我对数组的任何关系方面都不感兴趣(不需要搜索元素在数组等)。所以我认为 VARRAY 会最小化表格。由于数组中元素的顺序很重要,上面的代码是否应该创建另一个列(例如order)来存储列中元素的顺序?
    • @ggkmath - 我更新了我的答案。使用嵌套表看起来与使用 VARRAY 基本相同,只是没有硬编码限制。我还展示了一个存储索引的示例。
    • 太好了,谢谢贾斯汀!如果我确实知道数组的长度,是否更喜欢使用可变数组而不是嵌套表,因为可以预先定义内存分配?或者,出于某种原因,是否首选嵌套表?
    • @ggkmath - 从内存分配的角度来看确实没有任何好处——如果 varray 和嵌套表具有相同数量的元素,它们将消耗相同数量的 RAM。如果将来大小发生变化,或者您不想为不同大小的数组声明一堆不同的类型,那么嵌套表会更加灵活,因此大多数人只会在任何地方使用嵌套表。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-29
    • 2014-01-27
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-12
    相关资源
    最近更新 更多