Home » SQL & PL/SQL » SQL & PL/SQL » Problem with nested FOR Loop (Oracle 11.2.0.3.0 - Sun Solaris unix)
Problem with nested FOR Loop [message #630513] Mon, 29 December 2014 13:10 Go to next message
welchaz
Messages: 23
Registered: April 2005
Location: Tucson, AZ
Junior Member
In the following code, my inner for loop (which has 4 results) is getting executed all 4 times for each outer loop record -- I only want the first inner loop value for the first outer loop value, the 2nd for the 2nd, etc. The DBMS_OUTPUT results below the code show the repeating of all the inner loop values for each outer value.

DECLARE 
    CURSOR multi_svc IS 
      SELECT DISTINCT wonum, 
                      wk_area 
      FROM   uns_premisemore 
      WHERE  ts_last_update > SYSDATE - 2 
             -- need to figure out what to do for timeframe here... 
             AND id_premise <> ' ' 
             AND cis_premise IS NULL 
             AND ts_sent = To_date('1/1/1900', 'DD/MM/YYYY') 
      -- identifies it as a multi-premise service WR 
      ORDER  BY wonum; 
    v_sql        NUMBER(7) := 0; 
    v_text       VARCHAR2(1000); 
    v_prem_count NUMBER(6) := 0; 
    n            NUMBER(4) := 0; 
BEGIN 
    FOR svc_rec IN multi_svc LOOP 
        /* Get the count of GIS premise IDs for this multi-premise WR */ 
        SELECT Count(id_premise) 
        INTO   v_prem_count 
        FROM   uns_premisemore 
        WHERE  wonum = svc_rec.wonum 
               AND wk_area = svc_rec.wk_area 
               AND id_premise <> ' ' 
               AND cis_premise IS NULL; 

        IF v_prem_count > 1 THEN 
          -- it's a multi-premise svc WR that has gotten all GIS IDs back from BUD
           /* For the service WO rows, get the child R1M WRs from Maximo */ 
          BEGIN 
              FOR multi_rec IN (SELECT wonum, 
                                       wk_area, 
                                       id_premise, 
                                       gis_sp_id 
                                FROM   uns_premisemore 
                                WHERE  cd_seq = 1 
                                       AND id_premise <> ' ' 
                                       AND wonum = svc_rec.wonum 
                                       AND wk_area = svc_rec.wk_area) LOOP 
                  dbms_output.Put_line('Outer multi-rec id premise: ' 
                                       || multi_rec.id_premise); 

                  /* Get next R1M WR number from Maximo to update with this GIS premise ID */
                   FOR mx_child_rec IN (SELECT wonum, 
                                              t_workarea 
                                       FROM   workorder 
                                       WHERE  parent = multi_rec.wonum 
                                              AND t_jobtype = 'R1M') LOOP 
                      dbms_output.Put_line('Inner mx_child_rec wonum: ' 
                                           || mx_child_rec.wonum); 

                      BEGIN 
                          /* Update this R1M WR with the svc WR's GIS premise ID and SP ID */
                           UPDATE uns_premisemore 
                          SET    id_premise = multi_rec.id_premise, 
                                 gis_sp_id = multi_rec.gis_sp_id, 
                                 ts_last_update = SYSDATE 
                          WHERE  wonum = mx_child_rec.wonum 
                                 AND wk_area = mx_child_rec.t_workarea 
                                 AND id_premise = ' '; 
                      EXCEPTION 
                          WHEN OTHERS THEN 
                            v_sql := SQLCODE; 

                            v_text := 'WO# ' 
                                      || mx_child_rec.wonum 
                                      || 
                  ' - Error updating R1M WR with GIS prem ID from svc WR ' 
                            || multi_rec.wonum 
                            || ': ' 
                            || Substr(SQLERRM, 1, 200); 

                  dbms_output.Put_line(v_text); -- for testing 
                      END; 
                  END LOOP; 
              END LOOP; 
          EXCEPTION 
              WHEN no_data_found THEN 
                v_sql := SQLCODE; 

                v_text := 'WO# ' 
                          || svc_rec.wonum 
                          || 
' - Unable to populate GIS IDs into R1M WRs; APWR remark missing for svc WR' 
        ; 

dbms_output.Put_line(v_text); 
WHEN OTHERS THEN 
v_sql := SQLCODE; 

v_text := 'WO# ' 
          || svc_rec.wonum 
          || ' - Error populating GIS IDs into R1M WRs for svc WR: ' 
          || Substr(SQLERRM, 1, 200); 

dbms_output.Put_line(v_text); 
END; 
ELSE 
  v_sql := 12; 

  v_text := 'WO# ' 
            || svc_rec.wonum 
            || 
' - Supposed to be a multi-premise WR, but there is not more than 1 premise'; 

dbms_output.Put_line(v_text); 
END IF; 
END LOOP; 
END; 
/


Dbms output results:
Outer multi-rec id premise: 0384307877
Inner mx_child_rec wonum: 6059070
Inner mx_child_rec wonum: 6059071
Inner mx_child_rec wonum: 6059072
Inner mx_child_rec wonum: 6059073
Outer multi-rec id premise: 0384307882
Inner mx_child_rec wonum: 6059070
Inner mx_child_rec wonum: 6059071
Inner mx_child_rec wonum: 6059072
Inner mx_child_rec wonum: 6059073
Outer multi-rec id premise: 0384307887
Inner mx_child_rec wonum: 6059070
Inner mx_child_rec wonum: 6059071
Inner mx_child_rec wonum: 6059072
Inner mx_child_rec wonum: 6059073
Outer multi-rec id premise: 0384307892
Inner mx_child_rec wonum: 6059070
Inner mx_child_rec wonum: 6059071
Inner mx_child_rec wonum: 6059072
Inner mx_child_rec wonum: 6059073
Re: Problem with nested FOR Loop [message #630517 is a reply to message #630513] Mon, 29 December 2014 14:55 Go to previous messageGo to next message
Michel Cadot
Messages: 68647
Registered: March 2007
Location: Nanterre, France, http://...
Senior Member
Account Moderator

1/ Remove all WHEN OTHERS clause.
2/ I bet you can do this with only SQL but I have nothing to work with.
3/ If you post a working Test case: create table and insert statements along with the result you want with these data then we will work with your table and data.

Re: Problem with nested FOR Loop [message #630518 is a reply to message #630513] Mon, 29 December 2014 14:57 Go to previous messageGo to next message
Barbara Boehmer
Messages: 9090
Registered: November 2002
Location: California, USA
Senior Member
It looks like your inner and outer cursors are ordered by wonum and parent. If so, then you can use row_number to match the rows of the inner and outer cursors as shown below. The following is not tested, since you did not provide create table and insert statements for sample data. This is just an attempt at correcting your code enough to provide what you asked for and may not be the most efficient method of doing whatever it is you are trying to do.

              FOR multi_rec IN (SELECT wonum, 
                                       wk_area, 
                                       id_premise, 
                                       gis_sp_id,
                                       ROW_NUMBER () OVER (ORDER BY wonum) rnouter  
                                FROM   uns_premisemore 
                                WHERE  cd_seq = 1 
                                       AND id_premise <> ' ' 
                                       AND wonum = svc_rec.wonum 
                                       AND wk_area = svc_rec.wk_area) LOOP 
                  dbms_output.Put_line('Outer multi-rec id premise: ' 
                                       || multi_rec.id_premise); 

                  /* Get next R1M WR number from Maximo to update with this GIS premise ID */
                   FOR mx_child_rec IN (SELECT wonum, t_workarea
                                        FROM   (SELECT wonum, 
                                                       t_workarea,
                                                       ROW_NUMBER () OVER (PARTITION BY parent ORDER BY wonum) rninner
                                                FROM   workorder 
                                                WHERE  parent = multi_rec.wonum 
                                                AND t_jobtype = 'R1M') 
                                        WHERE  rninner = multi_rec.rnouter) LOOP 
                      dbms_output.Put_line('Inner mx_child_rec wonum: ' 
                                           || mx_child_rec.wonum); 

[Updated on: Mon, 29 December 2014 15:02]

Report message to a moderator

Re: Problem with nested FOR Loop [message #630521 is a reply to message #630518] Mon, 29 December 2014 15:25 Go to previous message
welchaz
Messages: 23
Registered: April 2005
Location: Tucson, AZ
Junior Member
Barbara, that seems to do the trick perfectly! Thank you so much
Previous Topic: How to get list of top 15 sql order by by buffer gets
Next Topic: Syntax for creating oracle type
Goto Forum:
  


Current Time: Fri Apr 26 21:27:59 CDT 2024