OracleArray构造必须使用有效OracleConnection创建ArrayDescriptor,类型名须与数据库完全一致(含大小写和schema),且setARRAY需配对OracleTypes.ARRAY,否则报ORA-00902等错误。
OracleArray 构造前必须先有有效的 Connection
oracle 的数组绑定不是纯内存操作,arraydescriptor 和 oraclearray 都强依赖底层 jdbc 连接的 oracle 特定上下文。如果用 datasource 获取连接后没传给 arraydescriptor.createdescriptor(),会直接抛 java.sql.sqlexception: invalid column type 或更隐晦的 ora-00902: invalid datatype。
- 必须用实际的
OracleConnection(而非普通Connection)构造 descriptor:ArrayDescriptor desc = ArrayDescriptor.createDescriptor("MY_NUM_ARRAY", (OracleConnection) conn); - 不能复用跨连接的
ArrayDescriptor—— 即使类型名相同,不同连接实例生成的 descriptor 互不兼容 - 若用 HikariCP 等连接池,注意
conn.unwrap(OracleConnection.class)是安全的,但别对已关闭的连接调用
OracleArray 初始化时类型名必须与数据库中 TYPE 完全一致(含大小写和 schema)
Oracle 对自定义集合类型的引用区分大小写,且默认大写。比如你在 SQL*Plus 里建的是:
CREATE OR REPLACE TYPE my_schema.my_num_array AS TABLE OF NUMBER;那么 Java 里传的类型名就得是
"MY_SCHEMA.MY_NUM_ARRAY",而不是 "my_num_array" 或 "MY_NUM_ARRAY"。
- 查当前 session 可见的 type:执行
SELECT * FROM USER_TYPES WHERE TYPE_NAME LIKE '%ARRAY%' - 如果 type 在其他 schema 下,必须带 schema 前缀,否则报
ORA-04043: object ... does not exist - 使用
DESCRIBE命令确认 type 是否为COLLECTION类型,非 collection(如 object type)不能用于OracleArray
批量设参时,setARRAY 必须配对使用 OracleTypes.ARRAY
用 PreparedStatement.setObject(int, oracleArray) 很容易失败 —— Oracle JDBC 驱动无法自动推断这是数组类型,会当成普通对象序列化,最终触发 ORA-01008: not all variables bound 或 ORA-00932: inconsistent datatypes。
- 正确写法只有一种:
stmt.setARRAY(1, oracleArray); // 注意是 setARRAY,不是 setObject
- 对应注册参数类型也得是:
stmt.registerOutParameter(1, OracleTypes.ARRAY, "MY_NUM_ARRAY"); // 仅出参需 register
- 驱动版本影响行为:12c 以上推荐用
ojdbc8.jar,旧版(如 ojdbc6)对嵌套数组或大数组支持弱,可能触发ArrayIndexOutOfBoundsException在内部序列化阶段
数组元素为自定义对象时,STRUCT 映射必须提前注册 Map
如果数组元素是 OBJECT 类型(例如 CREATE TYPE person_t AS OBJECT(name VARCHAR2(50), age NUMBER)),光有 ArrayDescriptor 不够,JDBC 还需要知道怎么把 Java 对象转成 Oracle STRUCT。
- 必须在 connection 上注册映射:
((OracleConnection) conn).setTypeMap(Collections.singletonMap("MY_SCHEMA.PERSON_T", Person.class)); -
Person.class需实现SQLData接口,或用STRUCT.toJDBC()手动构造字段顺序 - 字段名、顺序、数量必须与 DB 中
PERSON_T完全一致,否则报ORA-00600内部错误或静默截断
Oracle 数组绑定最麻烦的不是语法,而是 descriptor 生命周期、schema 名匹配、驱动类型推导这三处细节——错一个,错误信息就拐着弯儿不告诉你真实原因。
立即学习“Java免费学习笔记(深入)”;










