Oracle函数返回数字问题和性能表

时间:2016-09-05 09:39:45

标签: oracle performance

我(有时)在我的oracle数据库中有一个内存块变成了crasy ...很多会话sundenless相互阻塞,而问题是在一个函数中返回一个数字表并在另一个过程中使用。< / p>

编辑:使用通过其他会话等待事件读取

来阻止会话

首先,我的数字表:

CREATE OR REPLACE TYPE liste_lots as TABLE OF number(10)

以及填充表格的函数:

   function get_ot_idem_cursor( .. ) return liste_lots is
   res_type liste_lots;
   p_restriction_level number;

   cursor  curs_lvl_1 is select [...] ;                              
   row_lvl_1 curs_lvl_1%rowtype;         

   cursor curs_lvl_0 is  select [...] ;                         
   row_lvl_0 curs_lvl_0%rowtype;                                        

begin

    res_type := liste_lots();

     p_restriction_level := get_edi_line_restriction(p_edi_line);

     if p_restriction_level = 1 then

         open curs_lvl_1;
         loop
         fetch curs_lvl_1 into row_lvl_1;

         exit when curs_lvl_1%notfound;

             begin           

                  res_type.extend;
                  res_type(res_type.last) := row_lvl_1.lot_id;

             exception

             when others then 

                dbms_output.put_line('problème get_ot_idem_cursor ');
                dbms_output.put_line(sqlerrm);

                close curs_lvl_1;  

             end;

         end loop; 

         close curs_lvl_1;      


      else

         open curs_lvl_0;
         loop
         fetch curs_lvl_0 into row_lvl_0;

         exit when curs_lvl_0%notfound;

             begin           

                  res_type.extend;
                  res_type(res_type.last) := row_lvl_0.lot_id;

             exception

             when others then 

                dbms_output.put_line('problème get_ot_idem_cursor ');
                dbms_output.put_line(sqlerrm);

                close curs_lvl_0;

             end;

         end loop;          

         close curs_lvl_0;  

      end if;

      return res_type;   

       exception
       when others then
       if curs_lvl_0%isopen then
          close curs_lvl_0;
       end if;
        if curs_lvl_1%isopen then
          close curs_lvl_1;
       end if;

end; 

并用于其他部分:

liste_ots := get_ot_idem_cursor(v_lot, v_sr_ligne_lot.id );

         select min(l.lot_id) into result
        from lot l
       where l.des_tiers_id = p_pf_tiers_id
         and l.lot_nature = 'POS'
         and l.exp_tiers_id = v_sr_ligne_lot.ramasse_tiers_id                    
         and ot_id in ((select * from TABLE(liste_ots)))
         and l.lot_datheurcharg > sysdate - 3;  

当db变得糟糕(会话阻塞,非常慢)时,这是指向的代码的一部分:

select * from TABLE(liste_ots)

问题不是所有的时间,如果你有任何想法或建议......

提前致谢(对不起我的英语不好)

1 个答案:

答案 0 :(得分:0)

使用bulk collect而不是普通循环(逐个获取记录),因为循环中没有其他逻辑。通常,始终避免切换上下文(SQL到/从PL / SQL)

open curs_lvl_1;
fetch curs_lvl_1 bulk collect into res_type;
close curs_lvl_1;