【问题标题】:Calling a stored procedure with %ROWTYPE out param raise "Invalid column type: 1111"?使用 %ROWTYPE out 参数调用存储过程会引发“无效的列类型:1111”?
【发布时间】:2018-06-13 20:10:08
【问题描述】:

我正在使用 JDev 11.1.1.7.0 和 oracle Exp 11g 数据库

在我的 ADF 应用程序中,我试图调用一个存储过程,但我不断收到错误,最后一个错误是“无效的列类型:1111”。

我认为问题出在这条线上

st.registerOutParameter(8,Types.OTHER);

我的 AppModuleImpl 完整方法:

    public Row callProcWithRowOut(Object[] bindVars) {
      CallableStatement st = null;
      try  {
        st = getDBTransaction().createCallableStatement("begin ADF_ITEM_SOLD(?,?,?,?,?,?,?,?);end;",getDBTransaction().DEFAULT);
        st.registerOutParameter(8,Types.OTHER);
        if (bindVars != null) {
          for (int z = 0; z < bindVars.length; z++) {
            st.setObject(z + 1, bindVars[z]);
          }
        }
        st.executeUpdate();

        return (Row)st.getObject(8);
      } catch (SQLException e)  {
        throw new JboException(e);
      } finally  {
        if (st != null) {
          try {
            st.close();
          }
          catch (SQLException e) {}
        }    
      }
    }   

痕迹:

java.sql.SQLException: Invalid column type: 1111  
  at oracle.jdbc.driver.OracleStatement.getInternalType(OracleStatement.java:5344)
  at oracle.jdbc.driver.OracleCallableStatement.registerOutParameterInternal(OracleCallableStatement.java:153)
  at oracle.jdbc.driver.OracleCallableStatement.registerOutParameter(OracleCallableStatement.java:399)
  at oracle.jdbc.driver.OracleCallableStatement.registerOutParameter(OracleCallableStatement.java:581)
  at oracle.jdbc.driver.OracleCallableStatementWrapper.registerOutParameter(OracleCallableStatementWrapper.java:1765)
  at weblogic.jdbc.wrapper.CallableStatement_oracle_jdbc_driver_OracleCallableStatementWrapper.registerOutParameter(Unknown Source)   
  at model.BC.AppModule.AppModule_AMImpl.callProcWithRowOut(AppModule_AMImpl.java:1793)
  at model.BC.Views.SalesInvoiceItems_VOImpl.insertItems(SalesInvoiceItems_VOImpl.java:54)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)  
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
  at java.lang.reflect.Method.invoke(Method.java:597)     
  at oracle.adf.model.binding.DCInvokeMethod.invokeMethod(DCInvokeMethod.java:657)
  at oracle.adf.model.binding.DCDataControl.invokeMethod(DCDataControl.java:2143)
  at oracle.adf.model.bc4j.DCJboDataControl.invokeMethod(DCJboDataControl.java:3118)
  at oracle.adf.model.binding.DCInvokeMethod.callMethod(DCInvokeMethod.java:261)
  at oracle.jbo.uicli.binding.JUCtrlActionBinding.doIt(JUCtrlActionBinding.java:1635)
  at oracle.adf.model.binding.DCDataControl.invokeOperation(DCDataControl.java:2150)
  at oracle.jbo.uicli.binding.JUCtrlActionBinding.invoke(JUCtrlActionBinding.java:740)
  at oracle.adf.controller.v2.lifecycle.PageLifecycleImpl.executeEvent(PageLifecycleImpl.java:407)     
  at oracle.adfinternal.view.faces.model.binding.FacesCtrlActionBinding._execute(FacesCtrlActionBinding.java:252)
  at oracle.adfinternal.view.faces.model.binding.FacesCtrlActionBinding.execute(FacesCtrlActionBinding.java:210)
  at view.backing.SalesInvoicesUpdate.insertItems_action(SalesInvoicesUpdate.java:281)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)  
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
  at java.lang.reflect.Method.invoke(Method.java:597)     
  at com.sun.el.parser.AstValue.invoke(Unknown Source)     
  at com.sun.el.MethodExpressionImpl.invoke(Unknown Source)    
  at org.apache.myfaces.trinidad.component.MethodExpressionMethodBinding.invoke(MethodExpressionMethodBinding.java:46)
  at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
  at org.apache.myfaces.trinidad.component.UIXCommand.broadcast(UIXCommand.java:190)

可能是什么问题?

感谢您的宝贵时间。

【问题讨论】:

  • 您希望返回什么类型的值?我相信您需要对结构化类型使用 Oracle 特定的 ORADATA 机制,或者选择 Types.OTHER 之外的标准类型之一。如果您指定Types.OTHER,Oracle(JDBC 驱动程序)不知道如何编组数据。
  • 请不要将堆栈跟踪作为块引用发布,它会破坏缩进并使它们不可读。这次我给你修好了
  • @JimGarrison 感谢您的回复,proc 应该返回一个我的表的 %ROWTYPE。我尝试使用 Types.STRUCT 但没有。这是我不知道在java代码中使用哪种类型来映射数据库行类型的问题,没有可用的Types.ROW。
  • %ROWTYPE 是一个伪类型名,是结构类型的占位符。您需要了解实际的行布局结构并自己执行映射。自从我这样做(15 年)以来已经很长时间了,我已经忘记了细节,但当时有可能。但是必须提前知道行类型。如果你事先不知道行类型我不知道是否可以。
  • 我知道行结构,但我不知道如何执行此自定义映射。

标签: java plsql oracle11g oracle-adf


【解决方案1】:

正如我在评论中所说,通常不可能调用返回 non-sql 类型的存储过程(使用数据库特定的 API 有一些例外)。由于%ROWTYPEPl/Sql 类型,您必须修改您的过程以返回支持的(即SQL)类型。最简单的方法是返回与您的%ROWTYPE 对应的一些 OUT 参数,或者您甚至可以返回一个简单的字符串/varchar(此字符串可能包含所有属性的逗号分隔列表),然后解析此字符串客户端(Java)端。

我还在这里写了一个简单的例子,展示了如何处理这种情况的一种方法(http://easyorm.info/SProc)。此示例使用 EasyORM 库(简单的 JDBC 包装器),而不是普通的 JDBC,但它应该让您了解如何修改存储过程。

您还可以将您的 %ROWTYPE 编码为 Oracle 对象(sql 类型)并让您的存储过程返回该对象,但这种方法更复杂(有关示例,请参阅 Mapping an Oracle stored procedure result to a custom Java type (class)

【讨论】:

  • 好的,我选择了 Object 类型,它返回了一个 Struct 对象,但我无法访问它。我创建了一个像您的链接一样实现 SQLData 的类,但它不能将 Struct 对象转换为它。
  • 您仍然需要在 Connection 对象上调用 setTypeMap(在链接中有说明)
  • Right 注意到,在您发表评论前 30 秒...已修复并正常工作...谢谢 dsp_user 的帮助
猜你喜欢
  • 1970-01-01
  • 2015-12-10
  • 2016-03-13
  • 1970-01-01
  • 2019-09-18
  • 2012-11-03
  • 2020-01-09
  • 2022-06-15
  • 1970-01-01
相关资源
最近更新 更多