簡體   English   中英

無法將數組(BINARY_DOUBLE)從Java傳遞到Oracle存儲過程?

[英]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 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 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM