Oracle
 sql >> Baza danych >  >> RDS >> Oracle

plsql - jak zwrócić tablicę asocjacyjną do java

Zamierzam nadstawić kark i powiedzieć, że nie ma bezpośredniego sposobu na dostęp do typu danych zadeklarowanego jako TABLE OF varchar(30) INDEX BY VARCHAR(30) z JDBC.

Dokumentacja Oracle JDBC wspomina o typie elementu tablicy asocjacyjnej (np. pierwszy varchar(30) w twoim typie) w różnych miejscach, ale o ile widzę, nie mówi nic o kluczowym typie danych. Ponadto dokumentacja wspomina, że ​​tablice asocjacyjne są przekazywane i zwracane jako tablice Javy. To prowadzi mnie do podejrzenia, że ​​Oracle JDBC obsługuje tylko tablice asocjacyjne z BINARY_INTEGER jako kluczowy typ danych.

Tak więc, jeśli chcesz uzyskać dostęp do danych w tablicy asocjacyjnej PL/SQL za pomocą VARCHAR2 klucze z JDBC, polecam najpierw przekonwertować dane na inny typ danych.

Spodziewam się jednak, że napisany przez Ciebie kod JDBC obsłuży Twoją tablicę asocjacyjną z BINARY_INTEGER klucze, po zmianie OracleTypes.VARCHAR dla OracleTypes.NUMERIC w wywołaniu registerIndexTableOutParameter . Należy pamiętać, że zwrócona tablica Java będzie zawierać tyle elementów, ile wynosi największa wartość klucza, więc upewnij się, że maksymalna liczba elementów (drugi parametr registerIndexTableOutParameter ) jest do tego wystarczająco duży. Upewnij się również, że tablica asocjacyjna nie zawiera kluczy ujemnych ani zerowych, ponieważ sterownik JDBC również ich nie obsługuje.

Dla porównania, oto kod, którego użyłem do uzyskania tablic asocjacyjnych zadeklarowanych jako INDEX BY BINARY_INTEGER pracujący. Po pierwsze, pakiet i treść PL/SQL:

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

Po drugie, klasa 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));
    }
}

Kiedy uruchamiam klasę Java, otrzymuję następujące dane wyjściowe:

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



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Wyeliminuj zduplikowane wyniki w zapytaniu wybierającym, które zawiera kolumnę CLOB

  2. Wyzwalacz mutacji Wyroczni

  3. LUB Baza danych/typ w programie Oracle Express/SQL Developer

  4. Problemy z grupowaniem

  5. Jak zmusić Oracle do korzystania ze skanowania zakresu indeksów?