Collections pl/sql嵌套表循环

Collections pl/sql嵌套表循环,collections,plsql,oracle11g,Collections,Plsql,Oracle11g,我有一个pl/sql嵌套表集合,其中包含以下元素: AG~AG~1~14 US~BRANCH~1~24 NO~NO~2~10 KI~296~2~13 AI~AI~2~21 我必须查看第三个子元素中每个元素的值(不确定如何放置!),然后选择一个值最高的。 在上面的数据中,第三个子元素是1,1,2,2(紧跟第二个~)。 显然,这里含有2的元素更高。因此,其中3个符合标准。 此外,从其中的3个元素中,我必须查看第4个子元素,并最终选择具有最高值的元素。 这3个元素的第4个子元素是:10,13,21

我有一个pl/sql嵌套表集合,其中包含以下元素:

AG~AG~1~14
US~BRANCH~1~24
NO~NO~2~10
KI~296~2~13
AI~AI~2~21
我必须查看第三个子元素中每个元素的值(不确定如何放置!),然后选择一个值最高的。 在上面的数据中,第三个子元素是1,1,2,2(紧跟第二个~)。 显然,这里含有2的元素更高。因此,其中3个符合标准。 此外,从其中的3个元素中,我必须查看第4个子元素,并最终选择具有最高值的元素。 这3个元素的第4个子元素是:10,13,21 由于21是最高值,因此最终输出是拾取元素AI~AI~2~21

我正在努力以最好的方式做到这一点。 我尝试了instr和substr的各种组合,并循环它们进行比较。但是,它还不够模块化。 我还可以标记每个元素中的字符串,并将其放入对会话有效的全局临时表中,然后使用oracle sql获取最终数据。但是,我希望避免使用表和维护表等,如果可能的话,我希望将它保持在pl/sql中

declare
TYPE final_score_typ IS TABLE OF varchar2(1000);

l_final_score final_score_typ;

l_final_output varchar2(20);

begin

<code logic that populates the nested table containing the above data>

for j in 1..l_final_score.count loop

    dbms_output.put_line(l_final_score(j));

end loop;

dbms_output.put_line('final output string is:' || l_final_output);


end;
声明
类型最终得分类型为varchar2表(1000);
l_最终分数最终分数类型;
l_最终_输出varchar2(20);
开始
<填充包含上述数据的嵌套表的代码逻辑>
对于1..l_最终得分.count循环中的j
dbms_output.put_line(l_final_score(j));
端环;
dbms|u output.put_line('最终输出字符串为:'| | l|u final_output);
结束;
最终输出应打印为AI~AI~2~21 任何指点都将不胜感激。我至少可以根据它们来尝试……现在,我想不出好的替代方案

select min(column_value) keep (dense_rank first order by 
  to_number(regexp_substr(column_value, '[^~]+', 1, 3)) desc, 
  to_number(regexp_substr(column_value, '[^~]+', 1, 4)) desc
) 
into l_final_output 
from table(l_final_score)
注意:类型必须是全局的:

create TYPE final_score_typ AS TABLE OF varchar2(1000);

现有数据库类型可用于VARCHAR2(1000)表:`

SYS.DBMS\u DEBUG\u VC2COLL

您可以这样使用它:

declare
   l_data SYS.DBMS_DEBUG_VC2COLL := SYS.DBMS_DEBUG_VC2COLL
                                       ('AG~AG~1~14'
                                       ,'US~BRANCH~1~24'
                                       ,'NO~NO~2~10'
                                       ,'KI~296~2~13'
                                       ,'AI~AI~2~21'
                                       );
   l_result varchar2(100);
begin
   select column_value 
   into l_result
   from
   ( select column_value 
          , row_number() over
               (order by substr(column_value
                               ,instr(column_value,'~',1,2)+1
                               ,instr(column_value,'~',1,3)
                                    -instr(column_value,'~',1,2)-1
                               ) desc
               ,         substr(column_value,instr(column_value,'~',1,3)+1) desc
               ) as rn
     from table (l_data)
   ) where rn = 1;
   dbms_output.put_line(l_result);
end;

(当然,您也可以将它与Egor更优雅的regexp_substr代码一起使用。)

谢谢。但是,如何在pl/sql块中访问此全局集合类型以填充这些值?在我最初的文章中,我声明了一个本地pl/sql嵌套表集合类型,并填充了初始值。我按照您的建议创建了一个全局类型,名称为final_score_typ。但是,在pl/sql块中访问它是不起作用的。我这样声明:l_final_score final_score类型:=final_score类型();它给了我一个编译错误:“标识符final_score_typ”必须声明。如果集合中有数据可以生成tie,那么上面的查询不起作用,我不确定如何将所有这些tie数据作为结果返回。值:最终评分类型('KI~296~1~9'、'US~CA~2~11'、'CA~CA~2~11'、'KP~KOREA~2~14'、'KR~KOREA~2~14'、'US~CA~3~19'、'CA~CA~3~19')。在这里,'US~CA~3~19'和'CA~CA~3~19'都是有效的,因为它们的第三个子元素最高,第四个子元素的值与19相同,因此产生一个平局。在这里,我的输出应该是同时返回它们。目前,上述查询根据min逻辑选择“CA~CA~3~19”。