在 Oracle 中对集合类型“对象”进行批量收集

Posted

技术标签:

【中文标题】在 Oracle 中对集合类型“对象”进行批量收集【英文标题】:Bulk Collect on collection Type 'object' in Oracle 【发布时间】:2021-01-08 13:24:57 【问题描述】:

我有一个集合类型对象

create or replace 
TYPE     "COLLECTION_OBJECT"    AS OBJECT
(
    attribute1 integer,
    attribute2  date,
    attribute2 integer,
) ;

然后在我的 pl/sql 过程中,我有这样创建的集合表。

create or replace 
TYPE         "COLLECTION_TABLE"       as table of COLLECTION_OBJECT;

我正在像这样进行批量收集。

SELECT COLLECTION_OBJECT(attribut1,attribut3,attribut3,attribute4) BULK COLLECT
  INTO result_set
  FROM TABLE(COLLECTION_TABLE)

我在 pl/sql 函数中收集 COLLECTION_OBJECT 中的数据 3 次,上面的查询在 COLLECTION_OBJECT 中收集数据后将数据添加到 result_set 3 次。

我的问题是。

收集到 COLLECTION_OBJECT 中的数据会在每次批量收集到 result_set 时被清除,还是会一直累加到最后?

我尝试在线搜索得到,当批量收集运行时,它会在读取后释放内存,但我没有从 Type 对象中获得任何与批量收集相关的信息,所以我没有信心。

【问题讨论】:

【参考方案1】:

每次您使用批量收集时,它都会清除该集合并将其替换为正在收集的新数据。如果要将多个批量收集合并到一个集合中,则需要使用一个临时集合,收集到该集合中,然后使用 MULTISET 运算符将这些集合连接在一起。这方面的一个例子可以在下面找到。

程序

CREATE OR REPLACE TYPE COLLECTION_OBJECT AS OBJECT
(
    attribute1 INTEGER,
    attribute2 DATE,
    attribute3 INTEGER
);

CREATE OR REPLACE TYPE COLLECTION_TABLE AS TABLE OF COLLECTION_OBJECT;


DECLARE
    l_data        collection_table;
    l_temp_data   collection_table;
BEGIN
        SELECT COLLECTION_OBJECT (1, TO_DATE ('1-JAN-2020'), 2)
          BULK COLLECT INTO l_data
          FROM DUAL
    CONNECT BY LEVEL <= 5;

    DBMS_OUTPUT.put_line ('1. Count: ' || l_data.COUNT);

        SELECT COLLECTION_OBJECT (1, TO_DATE ('1-JAN-2020'), 2)
          BULK COLLECT INTO l_data
          FROM DUAL
    CONNECT BY LEVEL <= 7;

    DBMS_OUTPUT.put_line ('2. Count: ' || l_data.COUNT);

        SELECT COLLECTION_OBJECT (1, TO_DATE ('1-JAN-2020'), 2)
          BULK COLLECT INTO l_temp_data
          FROM DUAL
    CONNECT BY LEVEL <= 10;

    l_data := l_data MULTISET UNION ALL l_temp_data;

    DBMS_OUTPUT.put_line ('3. Count: ' || l_data.COUNT);
    
    SELECT COLLECTION_OBJECT (1, TO_DATE ('1-JAN-2020'), 2)
          BULK COLLECT INTO l_temp_data
          FROM DUAL
    CONNECT BY LEVEL <= 50;

    l_data := l_data MULTISET UNION ALL l_temp_data;

    DBMS_OUTPUT.put_line ('4. Count: ' || l_data.COUNT);
END;

结果

1. Count: 5
2. Count: 7
3. Count: 17
4. Count: 67

【讨论】:

以上是关于在 Oracle 中对集合类型“对象”进行批量收集的主要内容,如果未能解决你的问题,请参考以下文章

从 Oracle 游标批量收集列的子集

oracle plsql中同时记录类型、Collection和Bulk collect

批量收集到表类型的对象

如何批量收集到子查询中的 UDT 类型

plsql-Oracle 集合

什么时候在java中对字符串进行垃圾收集