我希望将一堆“未知”值从 Spring Java 应用程序传递给 Oracle 存储过程。数据有些结构化,因此目前我们有一个存储过程,它接受 2 个 clob,即数据的键/值对。第一个 clob 代表单个记录,第二个 clob 代表 clob 1 的许多子记录。
这似乎是一种非常低效的传递数据的方式,因为我们必须首先在 java 中构造字符串,然后必须在存储过程中解析数据。
我已经研究了 Oracle 记录结构,但是似乎您必须将记录结构中的每个字段映射到数据库表字段。这种方法的问题是 a) 我们每次发送的数据项不同(尽管有一组核心数据保持不变)和 b) 某些数据项仅用于决策目的,实际上并非如此持久化到数据库。
所以我的问题是:将此类数据传递到 Oracle 存储过程的最有效方法是什么?我们希望保持能够发送可变参数集的灵活性以及围绕数据具有某种相似结构的能力。
提前致谢。
巴里
最佳答案
您是否考虑过将数据作为 XML 传递到存储过程? Oracle可以处理XML data types 。 Stack Overflow 上也有一些相关问题:
- Java: Oracle XMLType + JDBC
- How to Oracle XMLTYPE in Hibernate
- Using MyBatis with Oracle XMLType function "existsNode()"
但是,在某些情况下,XML 可能会成为性能 killer 。另一种选择是使用 REF CURSOR 类型:
PreparedStatement stmt = connection.prepareStatement(
"DECLARE "
+ " records SYS_REFCURSOR; "
+ "BEGIN "
+ " OPEN records FOR "
+ " SELECT * FROM TABLE(?); "
+ " my_proc(records); "
+ "END;");
// Set the records as an array
stmt.setArray(1, records);
这将是一种在某种程度上结构化数据并在弱类型游标上进行操作的方法。上面的选择可以有任何形式。在此示例中,我假设您将绑定(bind)如下内容:
CREATE TYPE rec AS OBJECT (ID NUMBER(7), VALUE CLOB);
CREATE TYPE tab AS TABLE OF rec;
一个简单的示例过程实现,需要一个 TABLE OF VARCHAR2
REF CURSOR
:
CREATE OR REPLACE PROCEDURE my_proc(cur IN SYS_REFCURSOR) IS
-- Using a pre-existing TABLE TYPE from the SYS schema for the example
array ORA_MINING_VARCHAR2_NT;
BEGIN
FETCH cur BULK COLLECT INTO array;
FOR i IN array.FIRST .. array.LAST
LOOP
DBMS_OUTPUT.PUT_LINE(array(i));
END LOOP;
END;
JDBC 绑定(bind)将是
String[] strings = new String[] {"a", "b", "c"};
ArrayDescriptor desc = new ArrayDescriptor("ORA_MINING_VARCHAR2_NT", c);
ARRAY array = new ARRAY(desc, c, strings);
stmt.setArray(1, array);
stmt.executeUpdate();
对于TABLE OF OBJECT
数据类型,绑定(bind)有点棘手......
关于java - Oracle 存储过程结构化参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9259498/