pl / sql嵌套表循环

时间:2014-08-29 20:52:12

标签: 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

我必须查看第3个子元素中的每个元素的值(不确定如何放置它!)并选择具有最高值的元素。 在上面的数据中,第3个子元素是1,1,2,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;

最终输出应打印为AI~AI~2~21 任何指针都将非常感激。我可以根据它们进行至少尝试......现在,想不出好的替代品。

2 个答案:

答案 0 :(得分:1)

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);

答案 1 :(得分:0)

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

SYS.DBMS_DEBUG_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代码一起使用。)