[英]not possible to pass array (of BINARY_DOUBLE) from Java to Oracle stored procedure?
Using Java 1.7 and Oracle 11.2 database (with Glassfish 3.1.2), I need to get lots of java float
and double
arrays into an Oracle stored procedure. 使用Java 1.7和Oracle 11.2数据库(与Glassfish 3.1.2一起使用),我需要将许多Java float
和double
数组放入Oracle存储过程中。 Has anyone done this before? 有人做过吗?
Everything works fine if I try to pass an integer array, as follows: 如果我尝试传递整数数组,则一切正常,如下所示:
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";
}
But if I modify the above code to pass either BINARY_FLOAT or BINARY_DOUBLE, I get the error java.sql.SQLException: Internal Error: Array is in inconsistent status
: 但是,如果我修改上述代码以传递BINARY_FLOAT或BINARY_DOUBLE, java.sql.SQLException: Internal Error: Array is in inconsistent status
收到错误java.sql.SQLException: Internal Error: Array is in inconsistent status
:
----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";
}
Anyone know why this occurs? 有人知道为什么会这样吗? Or a workaround? 还是解决方法?
Here's the relevant section for Oracle 11.2 database regarding JDBC support of binary_float and binary_double: http://docs.oracle.com/cd/E11882_01/java.112/e16548/oraint.htm#JJDBC28153 这是Oracle 11.2数据库的相关部分,涉及对binary_float和binary_double的JDBC支持: http : //docs.oracle.com/cd/E11882_01/java.112/e16548/oraint.htm#JJDBC28153
As an alternative, I tried substituting: 作为替代方案,我尝试替换为:
cs.setPlsqlIndexTable(1, doubleArr, doubleArr.length, doubleArr.length, OracleTypes.BINARY_DOUBLE, 0);
but this led to the runtime error: 但这导致运行时错误:
java.sql.SQLException: Invalid PL/SQL Index Table element type
which I don't understand, since BINARY_DOUBLE is a valid OracleTypes (). 我不明白,因为BINARY_DOUBLE是有效的OracleTypes()。 http://docs.oracle.com/cd/E11882_01/appdev.112/e13995/oracle/jdbc/OracleTypes.html http://docs.oracle.com/cd/E11882_01/appdev.112/e13995/oracle/jdbc/OracleTypes.html
Lastly, I eliminated Glassfish (and it's JDBC connection pool) from the equation by substituting: 最后,我通过代入方程式来消除Glassfish(及其JDBC连接池):
OracleDataSource ods = new OracleDataSource();
ods.setURL("jdbc:oracle:thin:id/pwd@192.168.xxx.xxx:nnnn:sid");
conn = (OracleConnection) ods.getConnection();
but I still observed the same (initial) behavior (eg Array is in inconsistent status error). 但是我仍然观察到相同的(初始)行为(例如, 数组处于不一致状态错误)。
Try passing the array in as an array of BINARY_DOUBLE
objects instead of double
s. 尝试将数组作为BINARY_DOUBLE
对象的数组而不是double
传入。 The class BINARY_DOUBLE
is in the oracle.sql
package. BINARY_DOUBLE
类在oracle.sql
软件包中。
Converting the double[]
array to a BINARY_DOUBLE[]
array is straightforward: 将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]);
}
Once you've done this, create your ARRAY
from binDoubles
instead of doubleArray
. 完成此操作后,从binDoubles
而不是doubleArray
创建ARRAY
。
I was able to reproduce your error with a standalone console program that connected to the database using plain JDBC and then tried to call your stored procedure. 我能够使用独立控制台程序重现您的错误,该控制台程序使用纯JDBC连接到数据库,然后尝试调用您的存储过程。 When I made the change above, the error went away and I was able to call the stored procedure. 当我在上面进行更改时,错误消失了,我可以调用存储过程了。
The call to cs.setPlsqlIndexTable
would fail because this method works only with PL/SQL index-by tables, but your types are nested tables. 调用cs.setPlsqlIndexTable
将失败,因为此方法仅适用于PL / SQL索引表,但是您的类型是嵌套表。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.