【问题标题】:Is it possible to insert a table type collection within a table collection in PL/SQL是否可以在 PL/SQL 中的表集合中插入表类型集合
【发布时间】:2020-06-24 06:25:32
【问题描述】:

我需要在有 2 个字段的表集合中发回记录类型-

  1. Line_id
  2. Fulfillment_set_id

line_id 始终是唯一的,但 line_id 可以有多个 Fulfillment_set_id。 所以我创建了一个记录类型

Type fulfillment_set_id_tbl is Table of type NUMBER;

fulfillment_set_id_rec_tbl fulfillment_set_id_tbl := fulfillment_set_id_tbl(); 

Type line_rec is Record (
line_id NUMBER,
fulfillment_set_id fulfillment_set_id_tbl 
);

上述集合结构是否可行,或者我是否因为无法获得成功而遗漏了什么。以及如何将数据插入其中。

【问题讨论】:

    标签: sql plsql


    【解决方案1】:

    对于单个记录,试试这个:

    declare
        type fulfillment_set_id_tbl is table of number;
    
        type line_rec is record
            ( line_id number
            , fulfillment_set_id fulfillment_set_id_tbl );
    
        r line_rec;
    begin
        r.line_id := 1;
        r.fulfillment_set_id := fulfillment_set_id_tbl(10,11,12);
    end;
    

    对于行记录表:

    declare
        type fulfillment_set_id_tbl is table of number;
    
        type line_rec is record
            ( line_id number
            , fulfillment_set_id fulfillment_set_id_tbl );
    
        type line_rec_tbl is table of line_rec;
    
        r line_rec;
        line_recs line_rec_tbl := new line_rec_tbl();
    begin
        r.line_id := 1;
        r.fulfillment_set_id := fulfillment_set_id_tbl(10,11,12);
    
        line_recs.extend;
        line_recs(1) := r;
    end;
    

    从 Oracle 18c 中,我们获得了记录类型的伪构造函数(称为 'Qualified Expressions'),因此您可以以声明方式填充它们:

    declare
        type fulfillment_set_id_tbl is table of number;
    
        type line_rec is record
            ( line_id number
            , fulfillment_set_id fulfillment_set_id_tbl );
    
        type line_rec_tbl is table of line_rec;
    
        line_recs line_rec_tbl :=
            new line_rec_tbl
            ( line_rec(1, fulfillment_set_id_tbl(10,11,12))
            , line_rec(2, fulfillment_set_id_tbl(13,14,14))
            );
    begin
        dbms_output.put_line(line_recs(2).fulfillment_set_id(3));
    end;
    

    输出:

    14
    

    如果您要在 SQL 中将类型创建为独立对象,那么您可以更加灵活地使用自定义构造函数,并能够在查询中使用它们。

    顺便说一句,问题标题是指集合的集合,但这里的主要问题似乎是 PL/SQL 记录。希望这已经回答了这两个问题,但如果还没有,请告诉我。

    要实现cmets中提到的bulk collect,需要在SQL中定义一个集合类型,例如:

    create or replace type number_tt as table of number;
    

    那么它应该可以工作了:

    declare
        type line_rec is record
            ( line_id number
            , fulfillment_set_id number_tt );
    
        type line_rec_tbl is table of line_rec;
    
        line_recs line_rec_tbl;
    begin
        with demo (line_id, fulfillment_set_id) as
             ( select 1, 10 from dual union all
               select 1, 11 from dual union all
               select 1, 12 from dual union all
               select 2, 13 from dual union all
               select 2, 14 from dual union all
               select 2, 15 from dual )
        select line_id, cast(collect(fulfillment_set_id) as number_tt)
        bulk collect into line_recs
        from demo
        group by line_id;
        
        dbms_output.put_line('line_recs contains ' || line_recs.count || ' records');
    end;
    

    输出:

    line_recs contains 2 records
    

    【讨论】:

    • 感谢您提供如此详尽的答案。目前,我正在尝试将我的查询批量收集到 line_recs 表集合中,但我认为这在批量收集中是不可能的。我的方法是 select line_id, NULL bulk collect into line_recs from oe_order_lines_all where header_id='123';上面的查询在每条记录中返回 5 行,fulfillment_set_id 为 null。现在我将遍历整个表集合并为 fullfillment_set_id 设置值。我在查询中使用 bulk collect bc 的原因是我收集了 40 多个值,或者现在我必须一次添加所有 40 个值一条记录。
    • 我认为它只需要在 SQL 中定义您的“fulfillment_set_ids 表”集合类型。在我的回答中添加了建议。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-04
    • 1970-01-01
    相关资源
    最近更新 更多