Oracle
 sql >> Database >  >> RDS >> Oracle

plsql - come restituire l'array associativo a java

Alzerò il collo e dirò che non esiste un modo diretto per accedere a un tipo di dati dichiarato come TABLE OF varchar(30) INDEX BY VARCHAR(30) da JDBC.

La documentazione Oracle JDBC menziona il tipo di elemento dell'array associativo (ovvero il primo varchar(30) nel tuo tipo) in vari posti, ma per quanto posso vedere non dice nulla sul tipo di dati chiave. Inoltre, la documentazione menziona che gli array associativi vengono passati e restituiti come array Java. Questo mi porta a sospettare che Oracle JDBC supporti solo array associativi con BINARY_INTEGER come tipo di dati chiave.

Quindi, se vuoi accedere ai dati in un array associativo PL/SQL con VARCHAR2 chiavi da JDBC, consiglierei di convertire prima i dati in un altro tipo di dati.

Tuttavia, mi aspetto che il codice JDBC che hai scritto gestirà il tuo array associativo con BINARY_INTEGER chiavi, dopo aver modificato OracleTypes.VARCHAR per OracleTypes.NUMERIC nella tua chiamata a registerIndexTableOutParameter . Tieni presente che l'array Java restituito conterrà tanti elementi quanto il valore della chiave più grande, quindi assicurati che il numero massimo di elementi (il secondo parametro per registerIndexTableOutParameter ) è abbastanza grande per questo. Assicurati inoltre che l'array associativo non abbia chiavi negative o zero poiché il driver JDBC sembra non supportarle neanche.

Per riferimento, ecco il codice che ho usato per ottenere gli array associativi dichiarati come INDEX BY BINARY_INTEGER Lavorando. In primo luogo, il pacchetto PL/SQL e il 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;
/

In secondo luogo, la 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 eseguo la classe Java, ottengo il seguente output:

[4, 1, null, 2, null, null, 3]