Oracle
 sql >> Datenbank >  >> RDS >> Oracle

plsql - wie man ein assoziatives Array an Java zurückgibt

Ich werde meinen Hals herausstrecken und sagen, dass es keinen direkten Weg gibt, auf einen Datentyp zuzugreifen, der als TABLE OF varchar(30) INDEX BY VARCHAR(30) deklariert ist von JDBC.

Die Oracle JDBC-Dokumentation erwähnt den Elementtyp des assoziativen Arrays (d. h. das erste varchar(30) in Ihrem Typ) an verschiedenen Stellen, aber soweit ich sehen kann, sagt es nichts über den Schlüsseldatentyp aus. Darüber hinaus erwähnt die Dokumentation, dass assoziative Arrays als Java-Arrays übergeben und zurückgegeben werden. Dies lässt mich vermuten, dass Oracle JDBC nur assoziative Arrays mit BINARY_INTEGER unterstützt als Schlüsseldatentyp.

Wenn Sie also mit VARCHAR2 auf Daten in einem assoziativen PL/SQL-Array zugreifen möchten Schlüssel von JDBC, würde ich empfehlen, die Daten zuerst in einen anderen Datentyp zu konvertieren.

Ich würde jedoch erwarten, dass der von Ihnen geschriebene JDBC-Code Ihr assoziatives Array mit BINARY_INTEGER behandelt Tasten, sobald Sie OracleTypes.VARCHAR ändern für OracleTypes.NUMERIC in Ihrem Aufruf von registerIndexTableOutParameter . Beachten Sie, dass das zurückgegebene Java-Array so viele Elemente enthält wie der größte Schlüsselwert, also stellen Sie sicher, dass die maximale Anzahl von Elementen (der zweite Parameter von registerIndexTableOutParameter ) ist dafür groß genug. Stellen Sie außerdem sicher, dass das assoziative Array keine negativen oder Nullschlüssel enthält, da der JDBC-Treiber diese anscheinend auch nicht unterstützt.

Als Referenz ist hier der Code, den ich verwendet habe, um assoziative Arrays zu erhalten, die als INDEX BY BINARY_INTEGER deklariert wurden Arbeiten. Erstens das PL/SQL-Paket und den Hauptteil:

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

Zweitens die Java-Klasse:

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

Wenn ich die Java-Klasse ausführe, erhalte ich die folgende Ausgabe:

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