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

plsql - como retornar array associativo para java


Vou arriscar e dizer que não há uma maneira direta de acessar um tipo de dados declarado como TABLE OF varchar(30) INDEX BY VARCHAR(30) do JDB.

A documentação do Oracle JDBC menciona o tipo de elemento do array associativo (ou seja, o primeiro varchar(30) no seu tipo) em vários lugares, mas até onde posso ver não diz nada sobre o tipo de dados da chave. Além disso, a documentação menciona que arrays associativos são passados ​​e retornados como arrays Java. Isso me leva a suspeitar que o Oracle JDBC suporta apenas arrays associativos com BINARY_INTEGER como o tipo de dados chave.

Então, se você quiser acessar dados em um array associativo PL/SQL com VARCHAR2 keys do JDBC, eu recomendaria converter os dados em outro tipo de dados primeiro.

No entanto, eu esperaria que o código JDBC que você escreveu trate sua matriz associativa com BINARY_INTEGER chaves, depois de alterar OracleTypes.VARCHAR para OracleTypes.NUMERIC em sua chamada para registerIndexTableOutParameter . Esteja ciente de que a matriz Java retornada terá tantos elementos quanto o maior valor de chave, portanto, certifique-se de que o número máximo de elementos (o segundo parâmetro para registerIndexTableOutParameter ) é grande o suficiente para isso. Certifique-se também de que a matriz associativa não tenha chaves negativas ou zero, pois o driver JDBC também parece não oferecer suporte a elas.

Para referência, aqui está o código que usei para obter arrays associativos declarados como INDEX BY BINARY_INTEGER trabalhando. Em primeiro lugar, o pacote PL/SQL e o corpo:
create or replace PACKAGE testLookAside as
  type AssocArry IS TABLE OF number INDEX BY binary_integer;
  function lookupMasterData return AssocArry;
end testLookAside;
/

create or replace PACKAGE BODY testLookAside as
  function lookupMasterData return AssocArry as
    retval AssocArry;
  begin
    retval(2) := 1;
    retval(4) := 2;
    retval(7) := 3;
    retval(1) := 4;
    return retval;
  end lookupMasterData;
end testLookAside;
/

Em segundo lugar, a classe Java:
import java.math.BigDecimal;
import java.sql.*;
import java.util.Arrays;
import oracle.jdbc.OracleCallableStatement;
import oracle.jdbc.OracleTypes;

public class AssocArrayTest {
    public static void main(String[] args) throws Exception {
        Connection c = DriverManager.getConnection("url", "user", "password");
        OracleCallableStatement s = (OracleCallableStatement)c.prepareCall("{? = call testLookAside.lookupMasterData }");
        s.registerIndexTableOutParameter(1, 30, OracleTypes.NUMERIC, 0);
        s.execute();
        BigDecimal[] data = (BigDecimal[])s.getPlsqlIndexTable(1);
        System.out.println(Arrays.toString(data));
    }
}

Quando executo a classe Java, recebo a seguinte saída:
[4, 1, null, 2, null, null, 3]