我是PL / SQL的新手,目前我需要一个特定的功能,我怀疑它不适用于PL / SQL。我一定会使用PL / SQL,所以很遗憾对其他编程('查询')语言的提示对我没用。 因此,我想问一下,是否有可能在程序流程中在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);
该类型的创建没有任何问题。
在我的程序中,我有一个函数,需要声明这样的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包解析文档时,列表中填充了与要搜索的元素之一匹配的每个XML标记的键和值。由于XML标签在整个文档中可能不是唯一的,但多次出现,我想出了使用定义的SIMPLE_LIST来存储每一次出现的XML标签/元素(键)的值的想法。被搜寻。因此,LIST_OF_LISTS的'key'/'index'最终应包含XML标记/元素的名称,而SIMPLE_LIST应包含在一个列表中打包在一起的任何相应XML标记/元素的所有值。 要返回的列表中的条目数量相当小(绝对不超过100个条目),因此我假设在这种情况下使用实际表或嵌套表可能过度。
提前致谢。
克里斯
我测试了Boneist和Łukasiewicz先生的答案,我可以确认它们在应用于我的场景时都有效。我接受了后者,因为它是最紧凑的答案。
再次感谢您解决我的问题。
干杯, 克里斯
答案 0 :(得分:1)
也许这有帮助。
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;
答案 1 :(得分:0)