繁体   English   中英

在PL / SQL中创建动态对象

[英]Create Dynamic Objects in PL/SQL

我是PL / SQL的新手,目前我需要特定的功能,我怀疑它不能与PL / SQL一起使用。 我必须使用PL / SQL,因此不幸的是,其他编程语言(“查询”)的提示对我毫无用处。 因此,我想问一下,是否有可能在程序流程期间以及不仅在DECLARE块内在PL / SQL中创建用户定义类型的实例,并且在可能的情况下,我想知道如何做吧。

场景:

我想创建一个列表列表,例如...

TYPE SIMPLE_LIST IS TABLE OF VARCHAR2(30) INDEX BY VARCHAR(30);
TYPE LIST_OF_LISTS IS TABLE OF SIMPLE_LIST INDEX BY VARCHAR2(30);

类型的创建没有任何问题。

在我的程序中,我有一个函数,需要声明一个这样的LIST_OF_LISTS并动态填充它。

因此,简化的代码示例应类似于...

FUNCTION foo(...) RETURN ...
AS
  ll LIST_OF_LISTS;
  sl SIMPLE_LIST;
  ...
BEGIN
  LOOP  -- iterate over something
  ...
  sl := new SIMPLE_LIST; -- this surely doesn't work
  sl('key1') := ...;
  sl('key2') := ...;
  sl('key3') := ...;
  ...
  ll('iter_key') := sl;
  END LOOP;
  RETURN ll;
END foo;

我想要/需要使用这样的列表列表,因为在运行时之前我无法确定每个列表的长度(也不能确定列表的列表长度)。

就像已经知道的那样,我正在寻找一种类似于OO的功能,以在程序流程的中间创建一个带有“ new”运算符之类的类型的实例,以动态填充列表列表。 “ new”运算符只是我要完成的任务的提示,因为我知道这不是包含所描述任务的方式。

谁能给我提示我如何使用PL / SQL来实现所描述的方案?

编辑

您可能会感兴趣,这里有一些有关我要完成的实际任务的背景信息。 简而言之,函数'foo'将从xml文档中提取一些项目并返回打包在数据结构中的结果以供以后处理,这就是为什么我最终使用了这样的列表列表的原因。 函数foo接收一个xml文档(XMLTYPE),以及在文档解析期间要搜索的项目列表。 在使用DBMS_XMLDOM-package解析文档时,列表中会填充与要搜索的元素之一匹配的每个XML标签的键和值。 由于事实,XML标记在整个文档中可能不是唯一的,而是会多次出现,因此我想到了使用定义的SIMPLE_LIST将XML标记/元素(键)每次出现的值存储到的想法。被搜索。 因此,LIST_OF_LISTS的“键” /“索引”应最终包含XML标签/元素的名称,而SIMPLE_LIST应包含任何出现的相应XML标签/元素的所有值,并打包在一个列表中。 列表中要返回的条目数量将非常小(绝对不超过100个条目),因此,我认为在这种情况下使用实际表或嵌套表可能会过大。

提前致谢。

克里斯

EDIT²

我测试了Boneist和Łukasiewicz先生的答案,并且可以确定它们应用于我的场景时都可以使用。 由于这是最紧凑的答案,因此我接受了后者。

再次感谢您解决我的问题。

克里斯,干杯

也许这会有所帮助。

    declare 
      TYPE SIMPLE_LIST IS TABLE OF VARCHAR2(30) INDEX BY VARCHAR(30);
      TYPE LIST_OF_LISTS IS TABLE OF SIMPLE_LIST INDEX BY VARCHAR2(30);
        ll LIST_OF_LISTS;
        key_ll VARCHAR2(30);
        key_sl  VARCHAR2(30); 
    BEGIN
    --dynamic 
     for i in 1 .. 10 loop
        for j in 1..10 loop
          ll('i='||i)('j='||j) := 'value='||j;
        end loop;
     end loop;
-- static
     ll('A')('1'):='A1';
     ll('A')('2'):='A2';
     ll('A')('3'):='A3';
     ll('A')('4'):='A4';
     ll('A')('5'):='A5';    
     ll('B')('1'):='B1';
     ll('B')('2'):='B2';
     ll('B')('3'):='B3';
     ll('B')('4'):='B4';
     ll('B')('5'):='B5'; 



    -- and how to iterate it.
      key_ll := ll.first;
      while (key_ll is not null)
         loop
              key_sl := ll(key_ll).first;
              dbms_output.put_line(key_ll);
              while (key_sl is not null)
                 loop
                    dbms_output.put_line('   key sl: '||key_sl||' value sl: '||ll(key_ll)(key_sl));
                     key_sl :=  ll(key_ll).next(key_sl);
              end loop;

             key_ll := ll.next(key_ll);
      end loop;
    END foo;

我正在努力思考为什么可能要执行嵌套嵌套关联数组之类的正当理由,但是在不知道您要解决的问题的情况下,很难提出一种更好的方法(尽管极有可能存在!)。

话虽如此,我认为您正在苦苦挣扎的是一种通过list_of_lists外层数组的每次迭代将嵌套的关联数组(在您的示例中为simple_list)重置为空的方法。 有两种方法-一种是在处理sl数组的内容后使用sl.delete(),另一种是在处理中添加一个匿名PL / SQL块。

这是后者的一个示例:

declare
  type simple_list is table of varchar2(30) index by varchar(30);
  type list_of_lists is table of simple_list index by varchar2(30);

  ll_main list_of_lists;
  sub_sl_main simple_list;

  ll_idx varchar2(30);
  sl_idx varchar2(30);

  function foo
  return list_of_lists
  is
    ll list_of_lists;
  begin
    for j in 1..5
    loop

      declare
        sl simple_list;
      begin
        for i in 1..10
        loop
          if mod(i, j) = 0 then
            sl('key'||i) := 'value '||j||'_'||i;
          end if;
        end loop;

        ll('iter_key'||j) := sl;
      end;


    end loop;

    return ll;
  end;
begin
  ll_main := foo;

  ll_idx := ll_main.first;

  while (ll_idx is not null)
  loop    
    sub_sl_main := ll_main(ll_idx);

    sl_idx := sub_sl_main.first;

    while (sl_idx is not null)
    loop
      dbms_output.put_line('ll_idx = '||ll_idx||' and sl_idx = '||sl_idx||' and sub-list value = '||sub_sl_main(sl_idx));
      sl_idx := sub_sl_main.next(sl_idx);
    end loop;

    ll_idx := ll_main.next(ll_idx);
  end loop;
end;
/

ll_idx = iter_key1 and sl_idx = key1 and sub-list value = value 1_1
ll_idx = iter_key1 and sl_idx = key10 and sub-list value = value 1_10
ll_idx = iter_key1 and sl_idx = key2 and sub-list value = value 1_2
ll_idx = iter_key1 and sl_idx = key3 and sub-list value = value 1_3
ll_idx = iter_key1 and sl_idx = key4 and sub-list value = value 1_4
ll_idx = iter_key1 and sl_idx = key5 and sub-list value = value 1_5
ll_idx = iter_key1 and sl_idx = key6 and sub-list value = value 1_6
ll_idx = iter_key1 and sl_idx = key7 and sub-list value = value 1_7
ll_idx = iter_key1 and sl_idx = key8 and sub-list value = value 1_8
ll_idx = iter_key1 and sl_idx = key9 and sub-list value = value 1_9
ll_idx = iter_key2 and sl_idx = key10 and sub-list value = value 2_10
ll_idx = iter_key2 and sl_idx = key2 and sub-list value = value 2_2
ll_idx = iter_key2 and sl_idx = key4 and sub-list value = value 2_4
ll_idx = iter_key2 and sl_idx = key6 and sub-list value = value 2_6
ll_idx = iter_key2 and sl_idx = key8 and sub-list value = value 2_8
ll_idx = iter_key3 and sl_idx = key3 and sub-list value = value 3_3
ll_idx = iter_key3 and sl_idx = key6 and sub-list value = value 3_6
ll_idx = iter_key3 and sl_idx = key9 and sub-list value = value 3_9
ll_idx = iter_key4 and sl_idx = key4 and sub-list value = value 4_4
ll_idx = iter_key4 and sl_idx = key8 and sub-list value = value 4_8
ll_idx = iter_key5 and sl_idx = key10 and sub-list value = value 5_10
ll_idx = iter_key5 and sl_idx = key5 and sub-list value = value 5_5

不过,我几乎可以肯定,有一种更好的方法来做您想要做的事情!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM