![](/img/trans.png)
[英]Is it possible to pass a table of rowtype from java to an oracle stored procedure?
[英]not possible to pass array (of BINARY_DOUBLE) from Java to Oracle stored procedure?
使用Java 1.7和Oracle 11.2数据库(与Glassfish 3.1.2一起使用),我需要将许多Java float
和double
数组放入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 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";
}
有人知道为什么会这样吗? 还是解决方法?
这是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索引表,但是您的类型是嵌套表。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.