对 Oracle 存储函数的 JDBC 调用 - “结构表”类型的 IN 参数

Posted

技术标签:

【中文标题】对 Oracle 存储函数的 JDBC 调用 - “结构表”类型的 IN 参数【英文标题】:JDBC Call to Oracle Stored Function - IN parameter of type "table of struct" 【发布时间】:2013-07-05 21:52:30 【问题描述】:

我有一个复杂的 PL/SQL 存储函数,我必须在 JAVA 中调用这个函数。 这是程序:

FUNCTION SUB_REPORT_INCOMPLETE(p_ACT_ID IN ACTIVITIES.ID%TYPE,
                               p_MISSING TO_SUB_MISSING) RETURN VARCHAR2;

所以,正如你在这里看到的,我的第二个参数的类型是 TO_SUB_MISSING,它是一个 O_SUB_MISSING 的表:

CREATE OR REPLACE TYPE TO_SUB_MISSING AS TABLE OF O_SUB_MISSING;
CREATE OR REPLACE TYPE O_SUB_MISSING AS OBJECT (ACT_ID NUMBER, GIT_ID NUMBER, MISSING_QTY NUMBER);

经过一番研究,我写了这段代码:

Context context = new InitialContext();
DataSource dataSource = (DataSource) context.lookup(dataSourceName);
connection = dataSource.getConnection();

StructDescriptor structDescriptor = StructDescriptor.createDescriptor("O_SUB_MISSING", connection);
STRUCT[] structs = new STRUCT[listPieces.size()];
int ind = 0;
for (PieceEntity piece : listPieces) 
    Object[] params = new Object[3];
    params[0] = piece.getActId();
    params[1] = piece.getGitId();
    params[2] = piece.getMissingQty();
    STRUCT struct = new STRUCT(structDescriptor, connection, params);
    structs[ind++] = struct;

ArrayDescriptor desc = ArrayDescriptor.createDescriptor("TO_SUB_MISSING", connection);

statement = connection.prepareCall(Constants.DECLARE_INCOMPLETE_MODUL);
statement.registerOutParameter(1, OracleTypes.VARCHAR);
statement.setLong(2, agmId);
statement.setArray(3, new ARRAY(desc, connection, structs));
statement.executeQuery();

但是使用此代码,我在 StructDescriptor.createDescriptor 行上遇到异常:

java.lang.ClassCastException: org.apache.tomcat.dbcp.dbcp.PoolingDataSource$PoolGuardConnectionWrapper cannot be cast to oracle.jdbc.OracleConnection

我尝试通过在一些 *** 帖子中找到的两种解决方案来解决此异常,但没有奏效。

解决方案 1:

    OracleConnection oraConn = (OracleConnection) new DelegatingConnection(connection).getInnermostDelegate();

解决方案 2:

    OracleConnection oraConn = connection.unwrap(OracleConnection.class);

第一个解决方案抛出相同的异常,第二个抛出以下异常:

java.lang.AbstractMethodError: org.apache.tomcat.dbcp.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.unwrap(Ljava/lang/Class;)Ljava/lang/Object;

您知道如何解决我的问题吗?

【问题讨论】:

对于解决方案 1,您是否在上下文配置中设置了 accessToUnderlyingConnectionAllowed="true" 我尝试在我的 tomcat 服务器的 context.xml 中添加 ths :<parameter> <name>accessToUnderlyingConnectionAllowed</name> <value>true</value> </parameter> 但它没有改变任何东西。 【参考方案1】:

不是一个具体的解决方案,但它是一个提示:https://community.oracle.com/thread/718072?tstart=832 这可能会帮助您解决问题。

【讨论】:

以上是关于对 Oracle 存储函数的 JDBC 调用 - “结构表”类型的 IN 参数的主要内容,如果未能解决你的问题,请参考以下文章

java调用Oracle中的存储过程与存储函数

带有 PL SQL 表类型参数的 Oracle 存储过程的 JDBC 调用

如何从 jdbc 调用存储的函数?

JDBC取消Oracle存储过程调用

在某些参数类型是用户定义的情况下,如何使用 JDBC/Spring 调用 Oracle 存储过程?

使用简单的 jdbc 调用将数组作为输入参数传递给 oracle 存储过程