using nested_tables in java

▼魔方 西西 提交于 2019-12-13 05:28:30

问题


How do I receive a nested table in java from pl/sql procedure's OUT parameter? Here is my example code.

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

But when I try executing it I get the error PLS-00306: wrong number or types of arguments in call to 'procedure_name'

I am sure that the number of arguments are correct.


回答1:


This may answer your question

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

I am quoting this from the website above-

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.



回答2:


The way a nested table is recieved from an OUT parameter depends on how the table is nested consider a simple array type

object type

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

table type

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

Procedure

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;
/

The above procedure which returns a custom array type can be handled by

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();

    }

This works as a base on how you can recieve a table type i could still help you through if you can post your nested table type



来源:https://stackoverflow.com/questions/12060917/using-nested-tables-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!