Reputation: 4246
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
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