oracle - Issue with Bulk Collect -


i have procedure need fetch data cursor using bulk collect. issue approach - records getting processed , arent. unable identify root cause. when try debug issue, toad unresponsive , times out. here code. please help!

procedure getpendingitems(pprogramidlst in varchar2, eventcur out cur)          vsessionid            number;       vdefaultvalue         svoltp.param.defaultvalue%type;       type eventrec table of trigeventqueue.trigeventqueueid%type;       type eventpartitiondate table of trigeventqueue.partitiondate%type;       veventrec             eventrec;       veventpartitiondate   eventpartitiondate;       voldestpossibledate   date;       vtrigeventqueueid     varchar2 (250);       vprogramidlst         varchar2 (250);       vetinterval       number;       vcount            number;       vcount1 number;       cursor prcursor(vcount1    number)       select trigeventqueueid, partitiondate trigeventqueue       trigeventqueueid in (select trigeventqueueid            (  select teq.trigeventqueueid, teq.partitiondate, teq.eventprocessingsessionid,teq.trigeventstateid                      svoltp.trigeventqueue teq,                           programtrigevent pte,                           trigevent te                         teq.trigeventstateid = gceventstatepending                           , teq.eventprocessingsessionid null                           , teq.programtrigeventid = pte.programtrigeventid                           , pte.trigeventid = te.trigeventid                           , teq.partitiondate >                                  (sysdate - (te.numhoursuntileventexpired / 24))                           , teq.partitiondate > voldestpossibledate                  order teq.trigeventcreatedts)           rownum <= vcount1)           update of a.trigeventqueueid, a.partitiondate skip locked;    begin       vsessionid := trigeventsessionidseq.nextval;       vprogramidlst := pprogramidlst;       select defaultvalue         vdefaultvalue         svoltp.param        paramid = gcmaxpeneventsparam;         select defaultvalue         vetinterval         svoltp.param        paramid = 2755;       -- use max number of expiry hours identify oldest possible date/time event picked for.       select sysdate - (max (numhoursuntileventexpired) / 24)         voldestpossibledate         trigevent;          select count(1) vcount1            (   select teq.trigeventqueueid, teq.partitiondate                      svoltp.trigeventqueue teq,                           programtrigevent pte,                           trigevent te                         teq.trigeventstateid = gceventstatepending                           , teq.eventprocessingsessionid null                           , teq.programtrigeventid = pte.programtrigeventid                           , pte.trigeventid = te.trigeventid                           , teq.partitiondate >                                  (sysdate - (te.numhoursuntileventexpired / 24))                           , teq.partitiondate > voldestpossibledate                                           order teq.trigeventcreatedts)           rownum <= vdefaultvalue;      if vcount1 > 0           select count(1) vcount etinstancestatus                 datediff ('ss', instanceupdatetime, sysdate) < vetinterval;                 if vcount > 0                 vcount1 := round(vcount1/vcount);             else             vcount1  := vcount1;                 end if;           end if;        open prcursor(vcount1);       loop       fetch prcursor bulk collect veventrec, veventpartitiondate limit 100; --      exit when prcursor%notfound;       --svoltp.pkgsvoltplock.sleep(1);       forall in veventrec.first .. veventrec.last          update svoltp.trigeventqueue teq             set teq.eventprocessingsessionid = vsessionid,                 teq.trigeventstateid = gceventstatelocked,  --6 : locked state                 teq.lastuser = 1003,                 teq.lastupdate = sysdate               teq.trigeventqueueid = veventrec (i)                 , teq.partitiondate = veventpartitiondate (i);               end loop;       commit;       close prcursor;       open eventcur          select trigeventqueueid, programtrigeventid, partitiondate            svoltp.trigeventqueue teq               teq.eventprocessingsessionid = vsessionid                 , teq.trigeventstateid = gceventstatelocked                 , teq.partitiondate > voldestpossibledate;    exception       when others                open eventcur             select 1               dual              1 = 2;    end getpendingitems; 

it looks you've commented out exit part of attempt @ debugging - , causing toad unresponsive, means loop never exits (as tony andrews pointed out).

with exit had it, won't process if cursor query finds fewer 100 rows, you'll see prcursor%notfound though data retrieved. , if finds more 100 rows you'll process first batch, still lose records last batch of less 100.

so need move exit end of loop , change condition:

  loop   fetch prcursor bulk collect veventrec, veventpartitiondate limit 100;   --svoltp.pkgsvoltplock.sleep(1);   forall in 1 .. veventrec.count      update svoltp.trigeventqueue teq         set teq.eventprocessingsessionid = vsessionid,             teq.trigeventstateid = gceventstatelocked,  --6 : locked state             teq.lastuser = 1003,             teq.lastupdate = sysdate           teq.trigeventqueueid = veventrec (i)             , teq.partitiondate = veventpartitiondate (i);   exit when veventrec.count < 100;   end loop; 

i've changed forall loop use 1..count rather first..last won't have problem if last actual batch 100 rows, , next 1 gets 0 rows - it'll nothing in forall , exit.

this scenario covered in second half of this oracle magazine article ('kicking %notfound habit').


Comments

Popular posts from this blog

Fail to load namespace Spring Security http://www.springframework.org/security/tags -

sql - MySQL query optimization using coalesce -

unity3d - Unity local avoidance in user created world -