Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call oracle stored procedure which include user-defined type in java?

In Oracle DB:

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?

like image 775
xmurobi Avatar asked Sep 02 '10 10:09

xmurobi


People also ask

Which type of statement can be used for calling DB stored procedures?

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.

Which statement is used to call stored procedure in Java?

The CallableStatement of JDBC API is used to call a stored procedure. A Callable statement can have output parameters, input parameters, or both.

Which is used to call the stored procedures and functions in JDBC?

CallableStatement interface is used to call the stored procedures and functions.


2 Answers

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 
like image 73
Vincent Malgrat Avatar answered Sep 24 '22 13:09

Vincent Malgrat


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.

like image 45
Arlo Avatar answered Sep 24 '22 13:09

Arlo