java中如何调用带有数组类型参数的存储过程

不知道java中java.sql.Array如何使用
letitia61 ,没有看明白。我想向存储过程传递数组类型的参数,如何构造这个数组呢?比方说,我有一个String[] s={"a","b"} ,如何将其转换成java.sql.Array类型的对象呢?

java.sql
接口 Array
所有已知实现类:
SerialArray
SQL 类型 ARRAY 在 Java 编程语言中的映射关系。默认情况下,Array 值是对 SQL ARRAY 值的事务处理期引用。默认情况下,Array 对象是使用 SQL LOCATOR(array) 内部实现的,这意味着 Array 对象包含一个指向 SQL ARRAY 值中数据的逻辑指针,而不是包含 ARRAY 值的数据。

Array 接口提供了某些方法将 SQL ARRAY 值的数据作为数组或 ResultSet 对象传送到客户端。如果 SQL ARRAY 的元素是一个 UDT,那么可以自定义映射它们。要创建自定义映射关系,编程人员必须做两件事:

为将被自定义映射的 UDT 创建一个实现 SQLData 接口的类。
在类型映射表中生成一个项,该项包含
UDT 的完全限定 SQL 类型名称
实现 SQLData 的类的 Class 对象
在将带有对应于基本类型的项的类型映射表提供给 getArray 和 getResultSet 方法时,该表所包含的映射关系将用于映射 ARRAY 值的元素。如果没有提供类型映射表(通常是这种情况),则默认使用连接的类型映射表。如果该连接的类型映射表或为某一方法提供的类型映射表没有对应于基本类型的项,则根据标准映射关系来映射这些元素。

getArray()
以 Java 编程语言数组的形式检索由此 Array 对象指定的 SQL ARRAY 值的内容。

getArray(long index, int count)
检索由此 Array 对象指定的 SQL ARRAY 值的一部分,从指定 index 开始,包含 SQL 数组中 count 个连续元素。

getArray(long index, int count, Map<String,Class<?>> map)
检索由此 ARRAY 对象指定的 SQL Array 值的一部分,从指定 index 开始,包含 SQL 数组中 count 个连续元素。

getArray(Map<String,Class<?>> map)
检索由此 Array 对象指定的 SQL ARRAY 值的内容。

getBaseType()
在由此 Array 对象指定的数组中检索元素的 JDBC 类型。

getBaseTypeName()
在由此 Array 对象指定的数组中检索元素的 SQL 类型名称。

getResultSet()
检索包含此 Array 对象指定的 SQL ARRAY 值的元素的结果集合。

getResultSet(long index, int count)
检索保存子数组的元素的结果集合,从索引 index 开始,包含 count 个连续元素。

getResultSet(long index, int count, Map<String,Class<?>> map)
检索保存子数组的元素的结果集合,从索引 index 开始,包含 count 个连续元素。

getResultSet(Map<String,Class<?>> map)
检索包含由此 Array 对象指定的 SQL ARRAY 值的元素的结果集合。
温馨提示:答案为网友推荐,仅供参考
第1个回答  推荐于2018-03-29

1. 存储过程以及类型定义如下:

--The array in oracle
CREATE OR REPLACE TYPE idArray AS TABLE OF VARCHAR2(20);
 
--package header
CREATE OR REPLACE PACKAGE Lib_Package AS 
 PROCEDURE Book_Check_Procedure(ids IN idArray, exist OUT NUMBER); 
END Lib_Package;
 
--package body
CREATE OR REPLACE PACKAGE BODY Lib_Package AS
 
PROCEDURE Book_Check_Procedure( ids IN idArray,   exist OUT NUMBER) AS v_Index BINARY_INTEGER; BEGIN v_Index:= ids.FIRST; LOOP   SELECT COUNT(*) INTO exist FROM Lib_Duplicate WHERE status='Lent'     AND book_id=ids(v_Index);  EXIT WHEN v_Index=ids.LAST OR exist>0;  v_Index:= ids.NEXT(v_Index); END LOOP;END Book_Check_Procedure;
END Lib_Package;

2.在Java中调用上面的存储过程

(1) 在Oracle中定义数组类型idArray 
(2) 在java构造数组并转换成Oracle中定义的数组类型,调用存储过程

/**  * 当要删除图书时,检查是否仍然有图书复本处于借出状态  */ public boolean checkBookStatus(String[] bookIds) throws DataAccessException {
  boolean flag = false;  Connection conn = null;  OracleCallableStatement cstmt = null;  ArrayDescriptor desc = null;  ARRAY bookIdArray = null;  int count = 0;  String sql = "{call LIB_PACKAGE.Book_Check_Procedure(?,?)}";
  DbDriverManager dbManager = DbDriverManager.getInstance();  conn = dbManager.getConnection(Constants.DATABASE);
  try {   cstmt = (OracleCallableStatement) conn.prepareCall(sql);
   //定义oracle中的数组类型   desc = ArrayDescriptor.createDescriptor("IDARRAY", conn);   bookIdArray = new ARRAY(desc, conn, bookIds);
   cstmt.setObject(1, bookIdArray, oracle.jdbc.OracleTypes.ARRAY);   cstmt.registerOutParameter(2, Types.INTEGER);   cstmt.execute();   count = cstmt.getInt(2);
   log.info(this.getClass() + ".checkBookStatus: count = " + count);
   DbOperHelp.closeStatement(this.getClass(), cstmt);   DbOperHelp.closeConnection(this.getClass(), conn);  } catch (SQLException e) {
   log.error(this.getClass() + ".checkBookStatus-->SQLException: "     + e.getMessage());   DbOperHelp.closeStatement(this.getClass(), cstmt);   DbOperHelp.closeConnection(this.getClass(), conn);   throw new DataAccessException(     "When check the books, there is a SQLException: "       + e.getMessage(), e.getCause());  }
  if (count > 0) {
   flag = true;  }
  return flag; }

本回答被网友采纳
第2个回答  2008-05-30
跟普通一样
相似回答