Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Como chamar o procedimento com o parâmetro out como tipo de tabela de uma classe Java


Isso não é possível, consulte Acessando tabelas de índice PL/SQL por:

O Oracle JDBC não suporta RAW, DATE e PL/SQL RECORD como tipos de elemento.

Eu provavelmente usaria um tipo de objeto personalizado (global, não pacote) assim:
CREATE TYPE t_all_record AS OBJECT (
  x_object_type_id        number,
    x_object_name           varchar2(100),
    x_object_id             varchar2(70),
    x_audit_timestamp       timestamp(6),
    x_payload               clob
)
/
CREATE TYPE t_all_records IS TABLE OF t_all_record
/

faça referência à tabela de tipos em seu pacote (t_all_records em vez de tt_all_tab) e preencha-a assim
procedure get_data_Q1(x_object_id in varchar2 , x_all_type out t_all_records )
AS
begin
    SELECT t_all_record(O.object_type_id,O.object_name,O.object_id,A.audit_timestamp,P.payload)
    BULK COLLECT INTO x_all_type
    FROM APPLICATION APP, EXCEPTIONS E,MASTER_AUDIT A,MODULE_TYPE M,OBJECT_TYPE O,PAYLOAD P 
    WHERE ( A.MODULE_TYPE_ID = M.MODULE_TYPE_ID ) AND ( M.APPLICATION_ID = APP.APPLICATION_ID ) AND ( A.OBJECT_TYPE_ID = O.OBJECT_TYPE_ID ) AND ( O.OBJECT_ID = x_object_id )
end get_data_Q1;

O resultado será utilizável a partir de java assim:
package tests.jdbc;

import java.sql.Array;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSetMetaData;
import java.sql.Struct;
import java.sql.Types;

import oracle.sql.StructDescriptor;

public class OracleTableOfResult {
    public static void main(String...a) throws Exception {
        Class.forName("oracle.jdbc.OracleDriver");
        Connection connection = DriverManager.getConnection("jdbc:oracle:thin:<USER>/<PASS>@<DATABASEHOST>:1521:<SERVICE>");

        final String typeName = "T_ALL_RECORD";
        final String typeTableName = "T_ALL_RECORDS";

        // Get a description of your type (Oracle specific)
        final StructDescriptor structDescriptor = StructDescriptor.createDescriptor(typeName.toUpperCase(), connection);        
        final ResultSetMetaData metaData = structDescriptor.getMetaData();

        // Call the procedure (or whatever else) that returns the table of a custom type
        CallableStatement cs = connection.prepareCall("{call ult_pkg.get_data_Q1(?, ?)}");
        cs.setString(1, "the_id");
        // Result is an java.sql.Array...
        cs.registerOutParameter(2, Types.ARRAY, typeTableName);     
        cs.execute();

        // ...who's elements are java.sql.Structs
        Object[] data = (Object[]) ((Array) cs.getObject(2)).getArray();
        for(Object tmp : data) {
            Struct row = (Struct) tmp;
            // Attributes are index 1 based...
            int idx = 1;
            for(Object attribute : row.getAttributes()) {               
                System.out.println(metaData.getColumnName(idx) + " = " + attribute);                                            
                ++idx;
            }
            System.out.println("---");
        }
        cs.close();     
        connection.close();
    }
}

Mas no final, é questionável se vale a pena o esforço quando você pode usar sua consulta em uma instrução sql simples como uma instrução preparada…