从java访问包内定义的类型
Posted
技术标签:
【中文标题】从java访问包内定义的类型【英文标题】:Accessing types defined inside package from java 【发布时间】:2012-10-15 11:54:18 【问题描述】:我在 oracle 中的过程是在一个包下定义的,该包具有记录表的 in 和 out 参数。 我可以使用 java 中的可调用语句使用 packagename.procname 调用该过程。但是要访问 out 参数,我需要定义一个 ARRAY 类型的变量。但是oracle中的记录类型和记录表是在包里面定义的。因此这些类型不能使用 ARRAYDESCRIPTOR 从 java 中访问。
proc和类型定义如下:
CREATE OR REPLACE PACKAGE mypackage IS
TYPE TY_Pos IS RECORD
( cust_id VARCHAR2(9)
, balance NUMBER
);
TYPE TY_TBL IS TABLE OF TY_Pos INDEX BY PLS_INTEGER;
PROCEDURE myproc(inTable IN OUT TY_TBL,
count IN NUMBER,
outTable IN OUT TY_TBL
);
CREATE OR REPLACE PACKAGE BODY mypackage AS
PROCEDURE myproc(inTable IN OUT TY_TBL,
count IN NUMBER,
outTable IN OUT TY_TBL
) as
--proc body
为了访问作为记录表的 proc 的 out 变量,我将数组描述符创建为
ArrayDescriptor myDescp = ArrayDescriptor.createDescriptor ("TY_TBL", l_con);
但由于 TY_TBL 是在包内定义的,因此会引发错误。请帮助我如何从我的 java 代码中访问这种类型。
【问题讨论】:
它给出了 sql 异常,java.sql.SQLException: invalid name pattern。是的,附加包名称时抛出的异常是相同的。我不确定是否可以使用 refcursor 来访问该表。我使用 ArrayDescriptor 来获取定义为对象表的对象。 PL/SQL types are invisible to java。不过,您可以使用 SQL 类型(CREATE TYPE...)。 @VincentMalgrat,如果是这样,那么我应该怎么做才能读取输出?我想将所有这些(过程、类型)分组到一个包中。 我认为从 jdbc 访问 PLSQL 数组是不可能的,但最近的版本中可能有一些改进:见Creating package-level associative array in java 我从链接中找到的结论是“Oracle JDBC 不支持 RAW、DATE 和 PL/SQL RECORD 作为元素类型”这是否意味着我无法从 java 访问它我想从过程中访问的对象是 RECORD 类型的 TABLE? 【参考方案1】:TY_TBL 是 Pl/SQL 类型,这意味着该类型对 java 是不可见的。
我建议创建两个 sql 类型:
Create or Replace SQL_TY_Pos TYPE AS OBJECT (cust_id VARCHAR2(9), balance NUMBER);
Create or Replace SQL_TY_TBL TYPE IS TABLE OF SQL_TY_Pos INDEX BY PLS_INTEGER;
然后在java中:
ArrayDescriptor myDescp = ArrayDescriptor.createDescriptor ("SQL_TY_TBL", l_con);
【讨论】:
【参考方案2】:这不是一个非常干净的解决方案,但它确实有效
StringBuilder sql = new StringBuilder("DECLARE\n\tarr OTHERPACKAGE.TYPE;\n");
sql.append("BEGIN\n");
for (int i = 0; i < tmpArray.length; i++)
sql.append("\tarr(").append(i).append(") := '").append(tmpArray[i]).append("';\n");
sql.append("\tSCHEMA.PACKAGE.PROC(arr, ?);\n");
sql.append("END;");
Connection conn;
CallableStatement callableStatement = conn.prepareCall(sql.toString());
callableStatement.registerOutParameter(1, OracleTypes.CURSOR);
callableStatement.execute();
【讨论】:
以上是关于从java访问包内定义的类型的主要内容,如果未能解决你的问题,请参考以下文章