从 0jdbc6 JDBCthin 驱动程序调用具有自定义对象返回类型的 Oracle PL/SQL 过程

Posted

技术标签:

【中文标题】从 0jdbc6 JDBCthin 驱动程序调用具有自定义对象返回类型的 Oracle PL/SQL 过程【英文标题】:Calling an Oracle PL/SQL procedure with Custom Object return types from 0jdbc6 JDBCthin drivers 【发布时间】:2011-02-09 15:20:53 【问题描述】:

我正在编写一些 JDBC 代码,它调用具有自定义对象返回类型的 Oracle 11g PL/SQL 过程。每当我尝试注册我的返回类型时,根据我设置的类型执行语句时,我会收到 ORA-03115 或 PLS-00306 作为错误。下面是一个例子:

PLSQL 代码:

Procedure GetDataSummary (p_my_key    IN    KEYS.MY_KEY%TYPE,
                          p_recordset OUT   data_summary_tab,
                          p_status    OUT   VARCHAR2);

更多 PLSQL 代码(自定义对象详细信息):

CREATE OR REPLACE TYPE data_summary_obj
AS
   OBJECT (data_key             NUMBER,
           data_category        VARCHAR2 (100),
           sensitive_flag       VARCHAR2 (1),
           date_created         DATE,
           date_rep_received    DATE,
           date_first_offering  DATE,
           agency_data_ref      VARCHAR2 (13),
           change_code          VARCHAR2 (120),
           data_ref             VARCHAR2 (50),
           data_status          VARCHAR2 (100),
           data_count           NUMBER)
/

CREATE OR REPLACE TYPE data_summary_tab AS TABLE OF data_summary_obj
/ 

Java 代码:

String query = "begin manageroleviewdata.getdatasummary(?, ?, ?); end;");
CallableStatement stmt = conn.prepareCall(query);

stmt.setInt(1, 83);

stmt.registerOutParameter(2, OracleTypes.CURSOR); // Causes error: PLS-00306
stmt.registerOutParameter(3, OracleTypes.VARCHAR);

stmt.execute(stmt); // Error mentioned above thrown here.

谁能给我一个例子来说明我如何做到这一点?我想这是可能的。但是我看不到行集 OracleType。 CURSOR、REF、DATALINK 等失败。

抱歉,如果这是一个愚蠢的问题。我不是 PL/SQL 专家,可能在我的问题的某些领域使用了错误的术语。 (如果是,请编辑我)。

提前致谢。

注册,安德鲁

【问题讨论】:

【参考方案1】:

我终于(在其他人的帮助下)找到了答案。它分为三个部分:

首先是我需要使用:

OracleCallableStatement stmt = (OracleCallableStatement) conn.prepareCall(query);

而不是我一直尝试使用的简单 JDBC CallableStatement。

第二部分是我必须按如下方式注册我的“out”参数:

stmt.registerOutParameter(2, OracleTypes.STRUCT, "DATA_SUMMARY_TAB");

第三部分(在上面的第 2 部分中隐含)是“DATA_SUMMARY_TAB”必须大写。如果你把它放在小写,那么你会得到一个神秘的错误信息,如下所示:

java.sql.SQLException: invalid name pattern: MYTEST.data_summary_tab

在 oracle.jdbc.oracore.OracleTypeADT.initMetadata(OracleTypeADT.java:553) 在 oracle.jdbc.oracore.OracleTypeADT.init(OracleTypeADT.java:469) 在 oracle.sql.StructDescriptor.initPickler(StructDescriptor.java:390) 在 oracle.sql.StructDescriptor.(StructDescriptor.java:320)

就是这样。

另外,请注意我们的自定义对象类型不在任何包中。如果是这样,您可能需要稍微修改第三个参数。

【讨论】:

如果参数在包中,如何破解? 让我知道大小写【参考方案2】:

那里有两条不同的甚至可能相互矛盾的错误消息。

PLS-00306: wrong number or types of arguments in call to 'string' 

用户定义类型data_summary_tab的描述是什么? OracleTypes.CURSOR 需要一个 REF CURSOR,它等效于 JDBC ResultSet。而data_summary_tab 听起来可能是一个可变数组或嵌套表。

ORA-03115: unsupported network datatype or representation

这表明您使用的是比数据库服务器旧版本的客户端(比如 10g 甚至 9i)。通常我们可以摆脱它,但有时它会导致我们正在做不寻常的事情的错误。我不确定通过 JDBC 调用用户定义的类型是否应该算作“不常见的事情”,但我怀疑它可能。

【讨论】:

嗨@APC。谢谢你。最后一个错误是一个错字。我已经编辑了我的问题以纠正这个问题。我认为 PLS-00306 上的提示是正确的(我很确定我们使用的是正确的 JDBC 驱动程序)。我会看看并报告。

以上是关于从 0jdbc6 JDBCthin 驱动程序调用具有自定义对象返回类型的 Oracle PL/SQL 过程的主要内容,如果未能解决你的问题,请参考以下文章

是否可以使用具有两列的表视图创建 UI?

我可以使用具有不同字符串的一种布局吗?

用具有多个索引的数组填充表[重复]

为啥在传递 long long 时调用具有两个 double 类型参数的重载函数?

一件奇怪的祭祀用具?他的背景?

用具有不同范围的均匀分布的随机数填充多维矩阵