如题,在JAVA中如何调用?JAVA调用代码如下(一小部分):
//  cstmt.registerOutParameter( 15, oracle.jdbc.OracleTypes.ARRAY );
//  cstmt.registerOutParameter( 15, oracle.jdbc.OracleTypes.ROWID, "SMSSERVICE.MSG_ARRAY" );
//  cstmt.registerOutParameter( 15, oracle.jdbc.OracleTypes.JAVA_OBJECT, "SMSSERVICE.MSG_ARRAY" );
//  cstmt.registerOutParameter( 15, oracle.jdbc.OracleTypes.CURSOR, "SMSSERVICE.MSG_ARRAY" );
//  cstmt.registerOutParameter( 15, oracle.jdbc.OracleTypes.ARRAY, "SMSSERVICE.MSG_ARRAY" );
//  cstmt.registerOutParameter( 15, oracle.jdbc.OracleTypes.ARRAY );
//  cstmt.registerOutParameter( 15, oracle.jdbc.OracleTypes.ARRAY, "MSG_ARRAY" );
//  cstmt.registerOutParameter( 15, oracle.jdbc.OracleTypes.ARRAY );
//  cstmt.registerOutParameter( 15, oracle.jdbc.OracleTypes.REF );
    cstmt.registerOutParameter( 15, oracle.jdbc.OracleTypes.ARRAY, "SMSSERVICE.MSG_ARRAY" );
//  cstmt.registerOutParameter( 15, Types.ARRAY, "SMSSERVICE.MSG_ARRAY" );
//  cstmt.registerOutParameter( 15, oracle.jdbc.OracleTypes.ARRAY );
//  cstmt.registerOutParameter( 15, oracle.jdbc.OracleTypes.CURSOR, "SmsService.msg_array" );
//  cstmt.registerOutParameter( 15, oracle.jdbc.OracleTypes.CURSOR );// 执行存储过程
    cstmt.execute();
//  cstmt.executeUpdate();
Oracle代码如下:    --留言业务
    procedure LiuYan( srcaddr      varchar2, --源号码
                      srcaddrtype  varchar2, --源号码类型,0真实号码 1伪号码
                      dstaddr      varchar2, --目的号码
                      msg          varchar2, --消息内容
                      topid        varchar2, --栏目代码
                      srvcode      varchar2, --业务代码
                      cmd          varchar2, --命令码
                      linkid       varchar2, --mo的linkid
                      masterid     varchar2,
                      zoneid       varchar2,
                      param1       varchar2, --备用参数,扣费类型 0全部免费 1全部收费 2红名单免费
                      param2       varchar2, --备用参数
                      ret          out integer, --成功失败 0 成功 1 失败
                      retmsgc      out integer, --返回消息数目
                      retmsgs      out SmsService.msg_array --返回消息
                      );  Type sm_msg is Record
  (
      SendMsg varchar2(300):='',
      SendTo varchar2(50):='',
      SendToCodeType  varchar2(2):='0',  --接收号码类型,0  真实号码     1  伪码
      SendFrom varchar2(20):='',
      pid varchar2(4) :=sm_normal_pid,
      Dsc varchar2(4):='15',--sm_unicode_dcs,
      service varchar2(11):='',
      pri varchar2(4):=sm_normal_pri,
      report varchar2(4):=sm_requir_report,
      udhi varchar2(4):=sm_default_udhi,
      Fee_UserType varchar2(4):=sm_default_userfeetype,
      Fee_termial_id varchar2(50):='',
      Fee_termial_Type varchar2(2):='0',   --扣费号码类型,0  真实号码     1  伪码
      Msg_src varchar2(11):='',
      FeeType varchar2(4):=sm_default_feetype,
      FeeCode varchar2(7):='0',
      MoFlag varchar2(1):='0',
      GivenCode varchar2(7):='',
      AtTime      varchar2(17):='',          --计划下发时间
      ValidTime    varchar2(17):='',         --消息有效时间
      SmType   varchar2(4):= '3',    --//新增,消息类型
      FixedCode  varchar2(7):= '100000',   -- //新增,封项资费
      Linkid   varchar2(61):= '',     --//新增,MO的LINKID
      Transactionid varchar2(20) --可用于特殊标识MT消息话单,话单中保存
   );   type msg_array is table of sm_msg index by BINARY_INTEGER;
现在的问题是在JAVA中调用LiuYan存储过程的时候提示类型不匹配或类型不存在,注释中的方法全试过,还是不行~

解决方案 »

  1.   

    试一下stmt.registerOutParameter(15,Types.ARRAY,"<OracleUserName>.T_MODEL_ID"); 
      

  2.   

    你可以把过程 procedure LiuYan()的最后一个参数修改为cursor类型(如:retmsgs  out ref cursor),然后你在该过程中定义一个 v_obj_tab msg_array:=msg_array();类型的变量,把你查询所满足的所有记录装入v_obj_tab对象中,
    然后打开你传入的游标:
    open retmsgs  for  select * from Table(cast(v_obj_tab as msg_array));
    我就是这样实现的。
    你就可以在java代码中得到给游标对应的结果集了。注意:ref cursor应在一个全局包中定义成一个游标,然后在上面红字体部分调用。
      

  3.   

    哦,谢谢,但是不可以的~原系统已经运行了很长时间,很多其他的过程或程序是依赖他们的,真不知道他们原来是怎么调用的~而且在不改动他的情况下也有一个笨办法,就是我写另一个存储过程调用这个过程,然后另一个过程返回的类型是JAVA可读的也可以,但是……像这样的过程有几十个,如果要相对每个都重新编写一个过程实在……有些……。动态SQL我也试过,提示最后一个参数,就是上面有问题的这个是非Sql Type所以也不好用~
      

  4.   

    修改成这样试试:type msg_array is table of sm_msg;--嵌套表,不用你原来的索引表。 
      

  5.   

    还是不行,郁闷死了~再过几天割接了,实在不行就只能用笨办法了,对应他的存储,我每个再建一个存储,然后返回Oracle能识别的类型~
      

  6.   

    registerOutParameter
    void registerOutParameter(String parameterName,
                              int sqlType,
                              String typeName)
                              throws SQLException注册指定的输出参数。这种 registerOutParameter 方法应该用于用户命名的输出参数或 REF 输出参数。用户命名类型的示例包括:STRUCT、DISTINCT、JAVA_OBJECT 和指定数组类型。在执行存储过程调用之前,必须显式调用 registerOutParameter 为每个 OUT 参数注册来自 java.sql.Types 的类型。对于用户命名的参数,还应该提供该参数的完全限定 SQL 类型名称,而 REF 参数则要求提供所引用类型的完全限定类型名称。不需要类型代码和类型名称信息的 JDBC 驱动程序可以忽略它。不过,为了便于移植,应用程序应该为用户命名的参数和 REF 参数提供这些值。尽管此方法打算供用户命名的参数和 REF 参数使用,但可以将其用于注册任何 JDBC 类型的参数。如果该参数没有用户命名的类型或 REF 类型,则忽略 typeName 参数。 
    注:在读取 out 参数的值时,必须使用 getXXX 方法,其 Java 类型 XXX 对应于参数的已注册 SQL 类型。
      

  7.   

    哦,谢谢,关于忽略typeName的信息最近我也查到了,我也用两个参数试过,但……还是不好用,我把所有Oracle.Type都试过一遍的,但还是没有什么结果……,说实话,有些不好意思,没大看懂您说的前半段,Struct我也试过,不过一样报错,另外两个我再试下吧,谢啦~
      

  8.   

    看看:
    sql:
    http://blog.csdn.net/crazylaa/archive/2009/11/28/4897354.aspx
    java调用
    http://blog.csdn.net/crazylaa/archive/2009/11/28/4897361.aspx
      

  9.   


    请问一下 , 在java中如何调用 一个 带有 record 参数类型( in out) 的 procedure 啊 比如:create or replace procedure pro_add_emp(v_emp_rcd in out pkg_record.emp_record)pkg_record.emp_record  ==> create or replace package pkg_record is type emp_record is record(
           ename emp.ename%type,
           eno emp.empno%type   
     );end pkg_record;十分感谢, 这个问题 已经郁闷了我一下午了。
      

  10.   

    LZ这个问题解决没有?java能调用在包中的自定义类型否?