我希望从spring java应用程序向Oracle存储过程传递一堆“未知”值。数据有点结构化,所以目前我们有一个存储过程接受2个clobs,它们是数据的键/值对。第一个clob表示单个记录和第二个clob,表示clob 1的许多子记录。
这似乎是一种非常低效的传递数据的方法,因为我们必须在forst plave中用java构造字符串,然后必须在存储过程中解析数据。
我已经研究过Oracle记录结构,但是看起来好像你必须将记录结构中的每个字段映射到db表字段。这种方法的问题是:a)我们每次发送的数据项不同(尽管有一组核心数据保持不变)和b)某些数据项仅用于决策目的而不是实际的坚持到数据库。
所以我的问题是:将这些数据传递给Oracle存储过程的最有效的工具是什么?我们希望保持灵活性,能够发送变量参数集,同时在数据周围有一些相似的结构。
提前致谢。
巴里答案 0 :(得分:3)
您是否考虑过将数据作为XML传递给存储过程? Oracle可以处理XML data types。 Stack Overflow还有一些相关的问题:
然而,在某些情况下,XML可能是性能杀手。另一种选择是使用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);
这将是一种在某种程度上构建数据并在弱类型游标上运行的方法。上面的选择可以有任何形式。在这个例子中,我假设你将绑定这样的东西:
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绑定将
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
数据类型,绑定有点棘手......