Передача массива Object из Java в функцию PL / SQL - PullRequest
1 голос
/ 20 сентября 2019

Я пытаюсь создать объект массива Java (java.sql.Array), используя массив объектов.Мне нужно передать этот массив Java в хранимую процедуру PLSQL.

conn = ConnectionManager.getConnection();
JournalBean[] journal = listJournal.toArray(new JournalBean[listJournal.size()]); 
final Array sqlArray =   conn.createArrayOf("CHMCR.PACK_CHM_CR.FICHIER_CR_TYPE", journal);
cstmt = conn.prepareCall("{call CHMCR.PACK_CHM_CR.CHARGEMENT_CR(?,?,?,?,?)}");
cstmt.setArray(1,sqlArray);
cstmt.setString(2, fileName);
cstmt.registerOutParameter(3, oracle.jdbc.OracleTypes.NUMBER);
cstmt.registerOutParameter(4, oracle.jdbc.OracleTypes.NUMBER);
cstmt.registerOutParameter(5, oracle.jdbc.OracleTypes.VARCHAR);

cstmt.executeUpdate();
conn.commit();

однако, когда я пытаюсь создать этот массив, используя метод (connection.createArrayOf), я получаю следующее исключение:

java.sql.SQLException: Fonction non prise en charge
    at oracle.jdbc.driver.PhysicalConnection.createArrayOf(PhysicalConnection.java:9283)

это мой JournalBean:

public class JournalBean implements  Serializable, SQLData {

    private static final long serialVersionUID = 2199201954799483472L;

    private int idCr;
    private int idChargement;
    private String numAutorisation;
    private String version;

    @Override
    public String getSQLTypeName() throws SQLException {
        return "FICHIER_CR_TYPE";
    }

    @Override
    public void readSQL(SQLInput stream, String typeName) throws SQLException {
        idCr = stream.readInt();
        ...

    }

    @Override
    public void writeSQL(SQLOutput stream) throws SQLException {

        stream.writeInt(idCr);
        ...
    }
}

это мой новый DDL (создание типа в базе данных с использованием CREATE TYPE):

create or replace TYPE            CR_TYPE AS OBJECT
( ID_CR NUMBER  ,               
ID_CHARGEMENT   NUMBER ,
NUM_AUTORISATION    VARCHAR2(24 BYTE),
VERSION NUMBER 
) ;

, затем создание типа таблицы:

CREATE OR REPLACE TYPE FICHIER_CR_TYPE 
AS VARRAY(1000) OF CR_TYPE;

процедура имеетстал:

create or replace PACKAGE             PACK_CHM_CR
IS
   PROCEDURE CHARGEMENT_CR(
                                                              P_FICHIER_CR                       IN OUT FICHIER_CR_TYPE,
                                                              p_nom_fichier                        IN        VARCHAR2,                                         
                                                              p_id_chargement                       OUT NUMBER,
                                                              NMES                                        OUT NUMBER,
                                                              LMES                                        OUT VARCHAR2);
END PACK_CHM_CR;

Я использую Oracle 11g, Java 6 и я пробовал ojdbc14 и ojdbc6.

Ответы [ 2 ]

0 голосов
/ 20 сентября 2019
create or replace PACKAGE             PACK_CHM_CR
IS
   TYPE fichier_CR_TYPE IS TABLE OF CHMCR.JOURNAL_OPERATION_CHANGE%ROWTYPE index by binary_integer;

Вы не можете по трем причинам:

  1. TYPE x IS TABLE OF y INDEX BY z - это ассоциативный массив.Это исключительно тип данных PL / SQL, и JDBC не поддерживает передачу ассоциативных массивов, только типы данных коллекций или VARRAY (оба неассоциативных массива) (в отличие от C #, которые поддерживают только ассоциативные массивы, но не коллекции / VARRAY).
  2. Он определен в PACKAGE, который является областью PL / SQL.Если вы хотите передать тип, его необходимо определить в области SQL с помощью оператора CREATE TYPE.
  3. Драйвер JDBC не знает, как преобразовать ваш класс JournalBean в fichier_CR_TYPEтип базы данных.Вам нужно либо перейти к простому массиву (есть встроенные типы, которые можно использовать, например, SYS.ODCIVARCHAR2LIST), либо вам нужно указать Java, как сопоставлять класс и тип базы данных ( SQLData - это один из методов).

Необходимо устранить все 3 проблемы.


Обновление :

JournalBean класс не отображается на FICHIER_CR_TYPE, поскольку это массив;они должны иметь тип объекта CR_TYPE:

public class JournalBean implements  Serializable, SQLData {
  // ...
  public static final String SQL_TYPE = "CR_TYPE";

  @Override
  public String getSQLTypeName() throws SQLException {
    return SQL_TYPE;
  }
}

Вам также необходимо зарегистрировать тип с подключением:

conn = ConnectionManager.getConnection();

Map<String,Class<?>> typeMap = conn.getTypeMap();
typeMap.put( JournalBean.SQL_TYPE, JournalBean.class );

0 голосов
/ 20 сентября 2019

В соответствии с документацией createArrayOf ()

Array createArrayOf(String typeName, Object[] elements) throws SQLException

Если результирующий тип JDBC не является подходящим типом для данного typeName, тогда определяется реализацией, является ли исключение SQLExceptionвыброшен или драйвер поддерживает результирующее преобразование.

Ваше имя типа CHMCR.PACK_CHM_CR.FICHIER_CR_TYPE является пользовательским.Попробуйте использовать определенный тип и проверьте, исчезнет ли исключение.

Пожалуйста, найдите дополнительную информацию здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...