I have the following stored procedure:
procedure getInfo ( p_ids IN IDS_TABLE, p_details OUT cursor )
Type IDS_TABLE
is:
create or replace type IDS_TABLE as table of IDS create or replace type IDS as object ( id1 NUMBER, id2 NUMBER, id3 NUMBER )
How can I call getInfo in Java?
Creating and using a stored procedure in Java DB involves the following steps: Create the stored procedure with an SQL script or JDBC API. Call the stored procedure with the CALL SQL statement.
The CallableStatement of JDBC API is used to call a stored procedure. A Callable statement can have output parameters, input parameters, or both.
CallableStatement interface is used to call the stored procedures and functions.
Setting up a link between Oracle SQL objects and java objects manually is not a trivial task. In particular, arrays (or nested tables) of user-defined objects are more complex to pass from java to Oracle than arrays of standard datatypes. In other words, it is easier to call a procedure with signature:
(TABLE OF NUMBER, TABLE OF NUMBER, TABLE OF NUMBER)`
than a procedure whose signature is:
(TABLE OF (NUMBER, NUMBER, NUMBER)) <- your case
You can write a wrapper around your procedure to transform the second case into the first case.
That being said, it is by far not impossible to map your procedure. The following example is largely inspired by a post by Tom Kyte. Tom describes how to map a TABLE OF NUMBER
using oracle.sql.ARRAY
. In your case we will also have to use oracle.sql.STRUCT
to map the IDS
SQL object.
You may also want to browse the Oracle JDBC doc, in particular the chapter Working with Oracle Object Types.
First is a setup similar to yours:
SQL> CREATE OR REPLACE TYPE IDS AS OBJECT ( id1 NUMBER, id2 NUMBER, id3 NUMBER ); 2 / Type created SQL> CREATE OR REPLACE TYPE IDS_TABLE AS TABLE OF IDS; 2 / Type created SQL> CREATE OR REPLACE PROCEDURE getInfo(p_ids IN IDS_TABLE) IS 2 BEGIN 3 FOR i IN 1 .. p_ids.COUNT LOOP 4 dbms_output.put_line(p_ids(i).id1 5 || ',' || p_ids(i).id2 6 || ',' || p_ids(i).id3); 7 END LOOP; 8 END getInfo; 9 / Procedure created
This is the java procedure:
SQL> CREATE OR REPLACE 2 AND COMPILE JAVA SOURCE NAMED "ArrayDemo" 3 as 4 import java.io.*; 5 import java.sql.*; 6 import oracle.sql.*; 7 import oracle.jdbc.driver.*; 8 9 public class ArrayDemo { 10 11 public static void passArray() throws SQLException { 12 13 Connection conn = 14 new OracleDriver().defaultConnection(); 15 16 17 StructDescriptor itemDescriptor = 18 StructDescriptor.createDescriptor("IDS",conn); 19 20 Object[] itemAtributes = new Object[] {new Integer(1), 21 new Integer(2), 22 new Integer(3)}; 23 STRUCT itemObject1 = new STRUCT(itemDescriptor,conn,itemAtributes); 24 25 itemAtributes = new Object[] {new Integer(4), 26 new Integer(5), 27 new Integer(6)}; 28 STRUCT itemObject2 = new STRUCT(itemDescriptor,conn,itemAtributes); 29 30 STRUCT[] idsArray = {itemObject1,itemObject2}; 31 32 ArrayDescriptor descriptor = 33 ArrayDescriptor.createDescriptor( "IDS_TABLE", conn ); 34 35 ARRAY array_to_pass = 36 new ARRAY( descriptor, conn, idsArray ); 37 38 OraclePreparedStatement ps = 39 (OraclePreparedStatement)conn.prepareStatement 40 ( "begin getInfo(:x); end;" ); 41 42 ps.setARRAY( 1, array_to_pass ); 43 ps.execute(); 44 45 } 46 } 47 / Java created
Let's call it:
SQL> CREATE OR REPLACE 2 PROCEDURE show_java_calling_plsql 3 AS LANGUAGE JAVA 4 NAME 'ArrayDemo.passArray()'; 5 / Procedure created SQL> exec show_java_calling_plsql ; 1,2,3 4,5,6 PL/SQL procedure successfully completed
If you're using Spring, you may want to look at Spring Data JDBC Extensions, which provides a SqlArrayValue
type.
Chapter 7.2.1 Setting ARRAY values using SqlArrayValue for an IN parameter explains how to call procedures with array parameters.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With