繁体   English   中英

将 Object 数组从 Java 传递到 PL/SQL function

[英]Passing an array of Object from Java to PL/SQL function

我正在尝试使用对象数组创建 Java 数组(java.sql.Array)object。 我需要将这个 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。

根据createArrayOf() 的文档

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

如果生成的 JDBC 类型不是给定 typeName 的适当类型,那么它是由实现定义的,是抛出 SQLException 还是驱动程序支持生成的转换。

您的 typeName CHMCR.PACK_CHM_CR.FICHIER_CR_TYPE 是自定义的。 尝试使用定义的类型并检查异常是否会消失。

在此处查找更多详细信息。

 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是一个关联数组。 This is solely a PL/SQL data type and JDBC does not support passing associative arrays, only collections or VARRAYs (both non-associative array) data types (unlike in C# which only support associative arrays and not collections/VARRAYs).
  2. 它在PACKAGE中定义,这是一个 PL/SQL scope。 如果要传递类型,则需要使用CREATE TYPE语句在 SQL scope 中定义它。
  3. JDBC 驱动程序不知道如何将JournalBean class 转换为fichier_CR_TYPE数据库类型。 You either need to pass to a simple array (there are built-in types that can be used like SYS.ODCIVARCHAR2LIST ) or you need to tell Java how to map between the class and the database type ( SQLData is one method of doing this ) .

您需要解决所有这 3 个问题。


更新

JournalBean class 不 map 到FICHIER_CR_TYPE因为那是一个数组; 它们的类型应该是 object 类型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 );

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM