ggkmath
ggkmath

Reputation: 4246

newbie simple example using VARRAY with JDBC and PL/SQL stored procedure

I'm trying to create a simple example to understand how to store then retrieve (float array) data from/to a Java program to an Oracle database (11.2G) via a PL/SQL stored procedure based on VARRAY.

I've tried my best to put together the Java program, but there may be an error or two. I'm also stuck on how to write the PL/SQL code to write then read the VARRAY to/from the database. Any advice would be appreciated.

Java program:

// 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 stored procedure:

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;

Upvotes: 1

Views: 2467

Answers (1)

Justin Cave
Justin Cave

Reputation: 231671

It's pretty uncommon in PL/SQL to use a VARRAY since you have to specify a maximum length. It's much more common to use collections based on nested tables or associative arrays.

If you do want to use VARRAY based collections, you can do something like

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;
/

You can call the procedure from 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.

It would be much more common to declare and use a nested table type which ends up looking almost exactly the same as the VARRAY code just without the length limit

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;
/

If you want to store the order of the elements of the array

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;
/

Upvotes: 2

Related Questions