2012-02-13 234 views
2

我希望通过spring java应用程序将大量“未知”值传递给Oracle存储过程。数据是有点结构化的,所以目前我们有一个存储过程,它接受2个clob,数据的键/值对。第一个clob代表单个记录和第二个clob,代表许多clob 1的子记录。Oracle存储过程结构化参数

这似乎是一种非常低效的方式来传递数据,因为我们必须在forst plave中构建java中的字符串,然后再数据必须在存储的过程中解析。

我已经查看了Oracle记录结构,但它看起来好像您必须将记录结构中的每个字段映射到数据库表字段。这种方法的问题是:a)我们每次发送的数据项不同(虽然有一组核心数据保持不变),b)某些数据项仅用于决策目的,并非实际坚持到数据库。

所以我的问题是:什么是最有效的工具来传递这样的数据到Oracle存储过程?我们希望保持能够发送可变参数集以及数据周围具有某种结构的灵活性。

在此先感谢。

Barry

+1

如果你接受你以前的一些问题的答案,我已经得到了答案! – tbone 2012-02-13 12:37:10

+1

@tbone现在接受答案。希望你的建议:) – 2012-02-13 13:58:12

+0

起初是在思考XMLType的行,但看到卢卡斯的评论你拒绝了这种做法。你能举一个你需要传递给Oracle的数据的例子吗? – tbone 2012-02-13 14:34:24

回答

3

您是否考虑过将数据作为XML传递给存储过程? Oracle可以处理XML data types。也有堆栈溢出一些相关的问题:

然而,XML可能在某些情况下,一个性能杀手。另一种选择是使用REF游标类型:

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 VARCHAR2REF 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数据类型,绑定有点棘手...

+0

我应该提到,我们将传递数千个这样的记录,所以性能是一个问题,因此我们拒绝了xml。 – 2012-02-13 11:23:56

+0

@BazR:我明白了。看到更新的另一个想法 – 2012-02-13 12:47:23

+0

谢谢,这可能是一个选项。我猜想的问题是,我们希望保持数据的灵活性略微非结构化,但以有条理的方式整理数据,保持合理的性能水平。所以有我们的蛋糕和吃它:) – 2012-02-13 14:37:04