【问题标题】:Accessing the Custom Object Return type from oracle pl/sql in java在 java 中从 oracle pl/sql 访问自定义对象返回类型
【发布时间】:2018-08-26 22:06:45
【问题描述】:

我创建了一个签名如下的程序:

PROCEDURE CUSTOMER_LIST_FOR_SUSPICIOUS_CHECK (
      pCustNo             NUMBER,
      pCustomerList   OUT EMOB.PKG_FINGER.CUSTOMER_LIST,
      pErrorFlag      OUT VARCHAR2,
      pErrorMessage   OUT VARCHAR2);

所以我想从 java 调用这个过程。我研究了很多,得到了以下代码:

String query = "begin BIOTPL.PKG_FINGER.CUSTOMER_LIST_FOR_SUSPICIOUS_CHECK(?, ?, ?, ?); end;";
CallableStatement stmt = conn.prepareCall(query);

stmt.setInt(1, 83);
stmt.registerOutParameter(2, OracleTypes.ARRAY, "BIOTPL.PKG_FINGER.CUSTOMER_LIST");
stmt.registerOutParameter(3, OracleTypes.VARCHAR);
stmt.registerOutParameter(4, OracleTypes.VARCHAR);
stmt.execute();

但执行上述代码后,我收到以下错误:

Mar 18, 2018 10:25:09 AM testsimple.accha getAccha
SEVERE: null
java.sql.SQLException: invalid name pattern: BIOTPL.PKG_FINGER.CUSTOMER_LIST
    at oracle.jdbc.driver.SQLStateMapping.newSQLException(SQLStateMapping.java:70)
    at oracle.jdbc.driver.DatabaseError.newSQLException(DatabaseError.java:133)
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:199)
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:263)
    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:271)
    at oracle.jdbc.oracore.OracleTypeADT.initMetadata(OracleTypeADT.java:543)
    at oracle.jdbc.oracore.OracleTypeADT.init(OracleTypeADT.java:462)
    at oracle.sql.ArrayDescriptor.initPickler(ArrayDescriptor.java:1678)
    at oracle.sql.ArrayDescriptor.<init>(ArrayDescriptor.java:291)
    at oracle.sql.ArrayDescriptor.createDescriptor(ArrayDescriptor.java:206)
    at oracle.sql.ArrayDescriptor.createDescriptor(ArrayDescriptor.java:175)
    at oracle.sql.ArrayDescriptor.createDescriptor(ArrayDescriptor.java:158)
    at oracle.sql.ArrayDescriptor.createDescriptor(ArrayDescriptor.java:125)
    at oracle.jdbc.driver.NamedTypeAccessor.otypeFromName(NamedTypeAccessor.java:84)
    at oracle.jdbc.driver.TypeAccessor.initMetadata(TypeAccessor.java:89)
    at oracle.jdbc.driver.T4CCallableStatement.allocateAccessor(T4CCallableStatement.java:629)
    at oracle.jdbc.driver.OracleCallableStatement.registerOutParameterInternal(OracleCallableStatement.java:166)
    at oracle.jdbc.driver.OracleCallableStatement.registerOutParameter(OracleCallableStatement.java:207)
    at oracle.jdbc.driver.OracleCallableStatementWrapper.registerOutParameter(OracleCallableStatementWrapper.java:1584)
    at testsimple.accha.getAccha(accha.java:54)
    at testsimple.accha.main(accha.java:78)

customer_list的定义如下:

TYPE CUSTOMER_REC IS RECORD
   (
      CUST_NO     NUMBER,
      CUST_CODE   VARCHAR2 (50),
      CUST_NAME   VARCHAR2 (500)
   );

   TYPE CUSTOMER_LIST IS TABLE OF CUSTOMER_REC
      INDEX BY BINARY_INTEGER;

我不明白错误在哪里?请帮我解决错误并从 oracle pl/sql 过程中获取参数。

【问题讨论】:

  • 根据the documentation,Oracle JDBC 驱动程序仅支持标量数据类型的 PL/SQL 索引表。驱动程序不支持记录类型的索引表(table OF xxx INDEX BY yyy),您的代码将无法运行。在这种情况下,我会使用一个简单的结果集,传递自定义记录数组很麻烦,而且通常不可移植,各种数据库及其驱动程序以稍微不同的方式实现这一点。
  • 这种情况有什么解决办法?
  • 如果将记录类型更改为对象类型,可以吗?

标签: java oracle stored-procedures jdbc plsql


【解决方案1】:

Oracle 驱动程序为此用例提供了一个特殊的 API,称为 registerIndexTableOutParameter。您的代码如下所示:

((oracle.jdbc.OracleCallableStatement)stmt).registerIndexTableOutParameter(2, 500, OracleTypes.STRUCT, 0);

有关参数的详细信息,请参阅 JavaDoc: https://docs.oracle.com/database/121/JAJDB/oracle/jdbc/OracleCallableStatement.html#registerIndexTableOutParameter_int__int__int__int_

【讨论】:

  • java.sql.SQLException: 无效的 PL/SQL 索引表元素类型
  • 这可能是因为您的索引是二进制整数。你可以试试数字吗?
猜你喜欢
  • 2017-06-02
  • 2011-02-09
  • 2018-08-04
  • 2019-05-07
  • 2011-02-27
  • 1970-01-01
  • 2019-10-28
  • 1970-01-01
  • 2012-06-15
相关资源
最近更新 更多