Oracle 存储过程结构化参数

发布于 2025-01-05 00:15:41 字数 436 浏览 1 评论 0原文

我希望将一堆“未知”值从 Spring Java 应用程序传递给 Oracle 存储过程。数据有些结构化,因此目前我们有一个存储过程,它接受 2 个 clob,即数据的键/值对。第一个 clob 代表一条记录,第二个 clob 代表 clob 1 的许多子记录。

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

我研究了 Oracle 记录结构,但是似乎您必须将记录结构中的每个字段映射到数据库表字段。这种方法的问题是 a) 我们每次发送的数据项不同(尽管有一组核心数据保持不变)和 b) 一些数据项仅用于决策目的,实际上并非如此持久化到数据库。

所以我的问题是:将此类数据传递到 Oracle 存储过程的最有效方法是什么?我们希望保持能够发送可变参数集的灵活性以及围绕数据具有某种外观的结构。

提前致谢。

巴里

I wish to pass a bunch of 'unknown' values to an Oracle stored procedure from a spring java application. The data is somewhat structured, so currently we have a stored proc that has accepts 2 clobs what are key/value pairs of the data. The first clob represents a single record amd the second clob, represents many child records of clob 1.

This seems a very inefficient way to pass the data as we have to construct strings in java in the forst plave and then the data has to be parsed in the stored proc.

I have looked into Oracle record structures, however it appears as though you have to map each field in the record structure to a db table field. the problem with this approach is a) the data items that we send each time differ (although there is a core set of data that remains the same) and b) some of the data items are there for decision making purposes only and are not actualy persisted to the database.

So my question is: what is the most efficient vehicle to pass such data to the Oracle stored proc? We want to maintain the flexibilty of being able to send variable parameter sets along with having some semblance of structure around the data.

Thanks in advance.

Barry

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

孤者何惧 2025-01-12 00:15:41

您是否考虑过将数据作为 XML 传递到存储过程? Oracle 可以处理 XML 数据类型。 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 数据类型,绑定有点棘手......

Have you considered passing your data to the stored procedure as XML? Oracle can handle XML data types. There are also some related questions on Stack Overflow:

However, XML may be a performance killer in some situations. Another option is to use REF CURSOR types:

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);

That would be a way to somewhat structure the data and yet operate on weakly typed cursors. The above select could have any form. In this example, I'm assuming that you will be binding something like this:

CREATE TYPE rec AS OBJECT (ID NUMBER(7), VALUE CLOB);
CREATE TYPE tab AS TABLE OF rec;

A simple example procedure implementation expecting a 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;

The JDBC binding would then be

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();

With TABLE OF OBJECT data types, the binding is a bit more tricky...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文