0

如何从 pl/sql 过程的 OUT 参数接收 java 中的嵌套表?这是我的示例代码。

Connection connection = utilities.getConnectionToDb();
CallableStatement callableStatement = connection.prepareCall("{call procedure_name(?,?)}");
callableStatement.setLong(1, 23456);
callableStatement.registerOutParameter(2, Types.ARRAY);
callableStatement.executeQuery();

但是当我尝试执行它时,我收到错误 PLS-00306: wrong number or types of arguments in call to 'procedure_name'

我确信参数的数量是正确的。

4

2 回答 2

0

这可能会回答你的问题

http://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:8908169959941

我从上面的网站引用这个-

SQL> create or replace type numArray as table of number;
  2  /

Type created.

SQL> create or replace type dateArray as table of date;
  2  /

Type created.

SQL> create or replace type strArray as table of varchar2(255);
  2  /

Type created.

SQL> create or replace package demo_passing_pkg
  2  as
  3      procedure pass( p_in in numArray, p_out out numArray )
  4      as language java
  5      name 'demo_passing_pkg.pass_num_array( oracle.sql.ARRAY,
  6                                             oracle.sql.ARRAY[] )';
  7
  8      procedure pass( p_in in dateArray, p_out out dateArray )
  9      as language java
 10      name 'demo_passing_pkg.pass_date_array( oracle.sql.ARRAY,
 11                                              oracle.sql.ARRAY[] )';
 12
 13
 14      procedure pass( p_in in strArray, p_out out strArray )
 15      as language java
 16      name 'demo_passing_pkg.pass_str_array( oracle.sql.ARRAY,
 17                                             oracle.sql.ARRAY[] )';
 18  end;
 19  /

Package created.

SQL> set define off
SQL>
SQL> create or replace and compile
  2  java source named "demo_passing_pkg"
  3  as
  4  import java.io.*;
  5  import java.sql.*;
  6  import java.math.*;
  7  import oracle.sql.*;
  8  import oracle.jdbc.driver.*;
  9
 10  public class demo_passing_pkg extends Object
 11  {
 12
 13  private static void show_array_info( oracle.sql.ARRAY p_in )
 14  throws SQLException
 15  {
 16      System.out.println( "Array is of type      " +
 17                           p_in.getSQLTypeName() );
 18      System.out.println( "Array is of type code " +
 19                           p_in.getBaseType() );
 20      System.out.println( "Array is of length    " +
 21                           p_in.length() );
 22  }
 23
 24  public static void pass_num_array( oracle.sql.ARRAY p_in,
 25                                     oracle.sql.ARRAY[] p_out )
 26  throws SQLException
 27  {
 28      show_array_info( p_in );
 29      java.math.BigDecimal[] values = (BigDecimal[])p_in.getArray();
 30
 31      for( int i = 0; i < p_in.length(); i++ )
 32          System.out.println( "p_in["+i+"] = " + values[i].toString() );
 33
 34      Connection conn = new OracleDriver().defaultConnection();
 35      ArrayDescriptor descriptor =
 36         ArrayDescriptor.createDescriptor( p_in.getSQLTypeName(), conn );
 37
 38      p_out[0] = new ARRAY( descriptor, conn, values );
 39
 40  }
 41
 42  public static void
 43  pass_date_array( oracle.sql.ARRAY p_in, oracle.sql.ARRAY[] p_out )
 44  throws SQLException
 45  {
 46      show_array_info( p_in );
 47      java.sql.Timestamp[] values = (Timestamp[])p_in.getArray();
 48
 49      for( int i = 0; i < p_in.length(); i++ )
 50          System.out.println( "p_in["+i+"] = " + values[i].toString() );
 51
 52      Connection conn = new OracleDriver().defaultConnection();
 53      ArrayDescriptor descriptor =
 54         ArrayDescriptor.createDescriptor( p_in.getSQLTypeName(), conn );
 55
 56      p_out[0] = new ARRAY( descriptor, conn, values );
 57
 58  }
 59
 60  public static void
 61  pass_str_array( oracle.sql.ARRAY p_in, oracle.sql.ARRAY[] p_out )
 62  throws java.sql.SQLException,IOException
 63  {
 64      show_array_info( p_in );
 65      String[] values = (String[])p_in.getArray();
 66
 67      for( int i = 0; i < p_in.length(); i++ )
 68          System.out.println( "p_in["+i+"] = " + values[i] );
 69
 70      Connection conn = new OracleDriver().defaultConnection();
 71      ArrayDescriptor descriptor =
 72         ArrayDescriptor.createDescriptor( p_in.getSQLTypeName(), conn );
 73
 74      p_out[0] = new ARRAY( descriptor, conn, values );
 75
 76  }
 77
 78  }
 79  /

Java created.

SQL> set serveroutput on size 1000000
SQL> exec dbms_java.set_output( 1000000 )

PL/SQL procedure successfully completed.

SQL>
SQL> declare
  2      l_in strArray := strArray();
  3      l_out strArray := strArray();
  4  begin
  5      for i in 1 .. 5 loop
  6          l_in.extend;
  7          l_in(i) := 'Element ' || i;
  8      end loop;
  9
 10      demo_passing_pkg.pass( l_in, l_out );
 11      for i in 1 .. l_out.count loop
 12          dbms_output.put_line( 'l_out(' || i || ') = ' || l_out(i) );
 13      end loop;
 14  end;
 15  /
Array is of type      OPS$TKYTE.STRARRAY
Array is of type code 12
Array is of length    5
p_in[0] = Element 1
p_in[1] = Element 2
p_in[2] = Element 3
p_in[3] = Element 4
p_in[4] = Element 5
l_out(1) = Element 1
l_out(2) = Element 2
l_out(3) = Element 3
l_out(4) = Element 4
l_out(5) = Element 5

PL/SQL procedure successfully completed.
于 2012-08-21T19:15:41.073 回答
0

从 OUT 参数接收嵌套表的方式取决于表的嵌套方式 考虑简单的数组类型

对象类型

CREATE OR REPLACE
TYPE HR.TNAME 
AS
OBJECT( NO1 NUMBER,
NAME VARCHAR2(10)
);

表类型

CREATE OR REPLACE
TYPE HR.ITYPE_CUSTOM
IS TABLE OF tname;  

程序

CREATE OR REPLACE PROCEDURE HR.p_schema_level_out(IN1 IN varchar2,p_det OUT itype_custom)
AS
lc_var itype_custom := itype_custom();
BEGIN
lc_var.extend;
lc_var(1) := TNAME(NO1 => 1,NAME => 'TRAIL1');
lc_var(1).no1 :=  1;
lc_var(1).name := 'qwe';
p_det:= lc_var;
END;
/

上述返回自定义数组类型的过程可以通过

try {

        stmt = con.createStatement();

        // -----------------------------------------------------
        // Call PL/SQL Procedure
        // -----------------------------------------------------

        String s1 = "begin p_schema_level_out(?,?); end;";
        cstmt = (OracleCallableStatement) con.prepareCall(s1);
        cstmt.setString(1, "something");
        cstmt.registerOutParameter(2, Types.ARRAY, "ITYPE_CUSTOM");
        cstmt.execute();

        Object[] data = (Object[]) ((Array) cstmt.getObject(2)).getArray();
        for (Object tmp : data) {
            STRUCT row = (STRUCT) tmp;

            for (Object attribute : row.getAttributes()) {
                System.out.println(attribute);

            }

            cstmt.close();
            stmt.close();

        }
    } catch (SQLException e) {

        e.printStackTrace();

    }

这可以作为您如何接收表格类型的基础,如果您可以发布嵌套表格类型,我仍然可以帮助您完成

于 2012-11-28T13:14:38.070 回答