如何调用在java中包含用户定义类型的oracle存储过程?

2022-09-01 13:09:09

在 Oracle DB 中:

我有以下存储过程:

procedure getInfo ( p_ids IN IDS_TABLE, p_details OUT cursor )

类型为:IDS_TABLE

create or replace type IDS_TABLE as table of IDS    

create or replace type IDS as object ( id1 NUMBER, id2 NUMBER, id3 NUMBER )

如何在Java中调用getInfo?


答案 1

手动设置 Oracle SQL 对象和 Java 对象之间的链接并非易事。特别是,用户定义对象的数组(或嵌套表)从java传递到Oracle比标准数据类型数组更复杂。换句话说,使用签名调用过程更容易:

(TABLE OF NUMBER, TABLE OF NUMBER, TABLE OF NUMBER)`

而不是签名为:

(TABLE OF (NUMBER, NUMBER, NUMBER))   <- your case

您可以在过程周围编写一个包装器,以将第二个事例转换为第一个事例。


话虽如此,到目前为止,绘制您的程序并非不可能。下面的例子很大程度上受到Tom Kyte的一篇文章的启发。Tom 描述了如何使用 映射 。在您的情况下,我们还必须使用来映射SQL对象。TABLE OF NUMBERoracle.sql.ARRAYoracle.sql.STRUCTIDS

您可能还想浏览 Oracle JDBC 文档,特别是使用 Oracle 对象类型一章。

首先是类似于您的设置:

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

这是java过程:

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

我们称之为:

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

答案 2

如果您使用的是Spring,则可能需要查看Spring Data JDBC Extensions,它提供了一个类型。SqlArrayValue

7.2.1 章 使用 SQLArrayValue 为 IN 参数设置 ARRAY 值说明了如何使用数组参数调用过程。


推荐