gpt4 book ai didi

java - 无法将数组(BINARY_DOUBLE)从 Java 传递到 Oracle 存储过程?

转载 作者:行者123 更新时间:2023-11-30 03:20:38 25 4
gpt4 key购买 nike

使用 Java 1.7 和 Oracle 11.2 数据库(使用 Glassfish 3.1.2),我需要将大量 java floatdouble 数组放入 Oracle 存储过程中。以前有人这样做过吗?

如果我尝试传递整数数组,一切正常,如下所示:

create or replace TYPE TYPE_ARRAY_INT AS TABLE OF NUMBER; -- array of int
create or replace TYPE TYPE_ARRAY_SINGLE AS TABLE OF BINARY_FLOAT; -- array of single precision (e.g. float)
create or replace TYPE TYPE_ARRAY_DOUBLE AS TABLE OF BINARY_DOUBLE; -- array of double precision (e.g. double)

----ORACLE STORED PROCEDURE----
create or replace procedure SAVE_DATA (my_array IN TYPE_ARRAY_INT)
as
begin
NULL;
end SAVE_DATA;

----JAVA----
public String SaveData() throws Exception {
int[] intArray = new int[]{1,2,3}; // create integer array
Connection conn = null;
CallableStatement cs=null;
try {
Context context = new InitialContext();
DataSource ds = (DataSource) context.lookup("jdbc/myOraclePool");
OracleDataSource ods = ds.unwrap(OracleDataSource.class);
conn = (OracleConnection) ods.getConnection();
ArrayDescriptor des_int=ArrayDescriptor.createDescriptor("TYPE_ARRAY_INT", conn);
cs = conn.prepareCall("{call save_data(?)}");
ARRAY myArray_orcl = new ARRAY(des_int, conn, intArray);
cs.setArray(1, myArray_orcl);
cs.execute();
} catch (Exception e) {
} Finally {
conn.close();
}
return "0";
}

但是,如果我修改上述代码以传递 BINARY_FLOAT 或 BINARY_DOUBLE,则会收到错误 java.sql.SQLException: Internal Error: Array is in不一致状态:

----ORACLE STORED PROCEDURE----
create or replace procedure SAVE_DATA (my_array IN TYPE_ARRAY_DOUBLE)
as
begin
NULL;
end SAVE_DATA;

----JAVA----
public String SaveData() throws Exception {
double[] doubleArray = new double[]{1,2,3}; // create double array
Connection conn = null;
CallableStatement cs=null;
try {
Context context = new InitialContext();
DataSource ds = (DataSource) context.lookup("jdbc/myOraclePool");
OracleDataSource ods = ds.unwrap(OracleDataSource.class);
conn = (OracleConnection) ods.getConnection();
ArrayDescriptor des_double=ArrayDescriptor.createDescriptor("TYPE_ARRAY_DOUBLE", conn);
cs = conn.prepareCall("{call save_data(?)}");
ARRAY myArray_orcl = new ARRAY(des_double, conn, doubleArray);
cs.setArray(1, myArray_orcl);
cs.execute();
} catch (Exception e) {
} Finally {
conn.close();
}
return "0";
}

有谁知道为什么会出现这种情况吗?或者解决方法?

以下是 Oracle 11.2 数据库中有关 binary_float 和 binary_double 的 JDBC 支持的相关部分: http://docs.oracle.com/cd/E11882_01/java.112/e16548/oraint.htm#JJDBC28153

作为替代方案,我尝试替换:

cs.setPlsqlIndexTable(1, doubleArr, doubleArr.length, doubleArr.length, OracleTypes.BINARY_DOUBLE, 0);

但这导致了运行时错误:

java.sql.SQLException: Invalid PL/SQL Index Table element type

我不明白,因为 BINARY_DOUBLE 是有效的 OracleTypes ()。 http://docs.oracle.com/cd/E11882_01/appdev.112/e13995/oracle/jdbc/OracleTypes.html

最后,我通过替换从等式中消除了 Glassfish(及其 JDBC 连接池):

  OracleDataSource ods = new OracleDataSource();
ods.setURL("jdbc:oracle:thin:id/pwd@192.168.xxx.xxx:nnnn:sid");
conn = (OracleConnection) ods.getConnection();

但我仍然观察到相同的(初始)行为(例如数组状态不一致错误)。

最佳答案

尝试将数组作为 BINARY_DOUBLE 对象数组而不是 double 传入。 BINARY_DOUBLE 类位于 oracle.sql 包中。

double[] 数组转换为 BINARY_DOUBLE[] 数组非常简单:

   BINARY_DOUBLE[] binDoubles = new BINARY_DOUBLE[doubleArray.length];
for (int i = 0; i < doubleArray.length; ++i) {
binDoubles[i] = new BINARY_DOUBLE(doubleArray[i]);
}

完成此操作后,从 binDoubles 而不是 doubleArray 创建您的 ARRAY

我能够使用一个独立的控制台程序重现您的错误,该程序使用普通 JDBC 连接到数据库,然后尝试调用您的存储过程。当我进行上述更改时,错误消失了,并且我能够调用存储过程。

cs.setPlsqlIndexTable 的调用将会失败,因为此方法仅适用于 PL/SQL 索引表,但您的类型是嵌套表。

关于java - 无法将数组(BINARY_DOUBLE)从 Java 传递到 Oracle 存储过程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31417405/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com