Java:将数组发送到PL-SQL函数

时间:2010-09-29 08:17:38

标签: java oracle stored-procedures

我需要将一个对象数组传递给PL-SQL函数

我的ORACLE代码:

CREATE OR REPLACE
TYPE
        uu.ITEMTAB AS TABLE OF ITEMREC; 
/

CREATE OR REPLACE
TYPE
        uu.ITEMREC AS OBJECT (ID NUMBER,
                               NAME VARCHAR2(30)) 
/

Java类

public class ITEMREC {

    private int ID;
    private String NAME;

    public ITEMREC(int iD, String nAME) {
        super();
        ID = iD;
        NAME = nAME;
    }
    public int getID() {
        return ID;
    }
    public void setID(int iD) {
        ID = iD;
    }
    public String getNAME() {
        return NAME;
    }
    public void setNAME(String nAME) {
        NAME = nAME;
    }
}

Java代码:

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Types;

import oracle.sql.ARRAY;
import oracle.sql.ArrayDescriptor;

public class Testna {

    public static void main(String args[]) throws java.io.IOException, SQLException, ClassNotFoundException
    {

        ITEMREC[] myA = new ITEMREC[1];
        myA[0] = new ITEMREC(1, "BOB");

        Class.forName("oracle.jdbc.driver.OracleDriver");
        Connection con=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:ORCL","uu","uu");

        ArrayDescriptor desc= ArrayDescriptor.createDescriptor("ITEMTAB", con);  
        ARRAY array = new ARRAY(desc, con, myA);

        System.out.println("Connection created..............");
        String call = "{ ? = call mainpackage.fgetText(?) }";
        CallableStatement cstmt = con.prepareCall(call);
        cstmt.setQueryTimeout(1800);
        cstmt.registerOutParameter(1, Types.VARCHAR);
        cstmt.setArray(2, array);
        cstmt.executeUpdate();
        String val = cstmt.getString(1);
        cstmt.close();
        con.close();
        System.out.println(val);
    }   
}

注意:这里我只有一个对象,因为这只是为了测试。

我得到的新错误是:

ARRAY array = new ARRAY(desc, con, myA);

Exception in thread "main" java.sql.SQLException: Fail to convert to internal representation:

更新: 我已经更新了我的代码,

Thanx @Codo

1 个答案:

答案 0 :(得分:4)

比这稍微复杂一些。首先,您需要Oracle中的数组类型。它必须是全局的,即没有用PL / SQL包定义。

create or replace type NUM_ARRAY as table of number;

然后,您需要在Java中创建Oracle特定的数组:

int intArray[] = { 1,2,3,4,5,6 };

ArrayDescriptor desc= ArrayDescriptor.createDescriptor("NUM_ARRAY", con);  
ARRAY array = new ARRAY(desc, con, intArray);

现在可以将其传递给存储过程:

OraclePreparedStatement stmt =
  (OraclePreparedStatement)conn.prepareStatement("begin pkg.proc(:x); end;");
ps.setARRAY( 1, array_to_pass );  
ps.execute();

我不太确定使用 oracle.jdbc 包中的Oracle特定类是多么重要。但是使用纯JDBC肯定是不可能的。

如果您提供有关阵列类型的更多信息(包括Java和Oracle端)以及PL / SQL过程的签名,我可以为您提供更具体的建议。

<强>更新

显然,你不是要尝试传递一个数组而是一个表。我从来没有这样做过,我不知道是否可能。