Learning... cursor and loop... suggestions?

Although I'm looking for non version specific information...  Here is what I'm running on.
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
PL/SQL Release 11.2.0.3.0 - Production
CORE    11.2.0.3.0    Production
TNS for Solaris: Version 11.2.0.3.0 - Production
NLSRTL Version 11.2.0.3.0 - Production
I'm trying to figure out the whole relationship and execution of inserting data into a table, manipulating the table and anything else via a procedure using a cursor and a loop.
Sounds simple, but all the examples I find out there all deal with dbms_output..  obviously because it's 'safe'...
So I'm trying to use context that my mind makes quick sense of.
I built a simple table with vehicle makes, with the intention of using exercises to add models, trim levels, engines...pretty much all vehicle specifications.
CREATE TABLE VEH_COMP
  MAKE          VARCHAR2(20 BYTE),
  MODEL         VARCHAR2(50 BYTE),
  TRIM          VARCHAR2(50 BYTE),
  ENGINE        VARCHAR2(50 BYTE),
  TRANSMISSION  VARCHAR2(50 BYTE),
  HORSEPOWER    NUMBER,
  TORQUE        NUMBER
TABLESPACE USERS
RESULT_CACHE (MODE DEFAULT)
PCTUSED    0
PCTFREE    10
INITRANS   1
MAXTRANS   255
STORAGE    (
            INITIAL          80K
            NEXT             1M
            MINEXTENTS       1
            MAXEXTENTS       UNLIMITED
            PCTINCREASE      0
            BUFFER_POOL      DEFAULT
            FLASH_CACHE      DEFAULT
            CELL_FLASH_CACHE DEFAULT
LOGGING
NOCOMPRESS
NOCACHE
NOPARALLEL
MONITORING;
Next I tried to build a simple sql block to insert a handful of Auto makes into the table...  I know this is ugly, and here is where I'm looking for suggestions for improvement.
DECLARE
   CURSOR m1
   IS
   SELECT 'Ford' as make FROM DUAL
UNION ALL
SELECT 'Chevy' FROM DUAL
UNION ALL
SELECT 'Dodge' FROM DUAL
UNION ALL
SELECT 'BMW' FROM DUAL
UNION ALL
SELECT 'Audi' FROM DUAL
UNION ALL
SELECT 'Mercedes' FROM DUAL;
BEGIN
   FOR v_make IN m1
   LOOP
      dbms_output.put_line(v_make.make);
      insert into veh_comp (make) values (v_make.make);
   END LOOP;
END;
Now I'm looking to add models.  Like Ford Mustang, Ford Lightning, Chevy Corvette, Chevy Camaro, Dodge Charger, Dodge Challenger, Dodge Viper, BMW M5, BMW M3, BMW M6...
Then I need to add engine sizes...  I6, V8
Then I need to add transmission... M6, M5, A5, A6, A8
I'm a little confused as how I should execute this part.  Or better yet, I'm sure there is a better way to include it all at once...
I've been looking on line on how to do this and again...only really finding dbms_output.put_line.  And I did grasp how I could do something along this lines from using a spool file.  But I really want to learn to be more efficient.
What's the best way to do this?
Thanks.

From what I can gather from the code, if I create some example data, you just want a query that does something like...
SQL> select * from vw_ta;
       LID        SID         C0         C1         C2         C3
         1          1          1          2          3          4
         1          2          1          2          3          4
         1          3          1          2          3          4
         1          4          1          2          3          4
         1          5          1          2          3          4
         1          6          1          2          3          4
         2          1          1          2          3          4
         2          2          1          2          3          4
         2          3          1          2          3          4
         3          1          1          2          3          4
         3          2          1          2          3          4
         3          3          1          2          3          4
         3          4          1          2          3          4
         3          5          1          2          3          4
         3          6          1          2          3          4
         3          7          1          2          3          4
         4          1          1          2          3          4
         5          1          1          2          3          4
         5          2          1          2          3          4
19 rows selected.
SQL> ed
Wrote file afiedt.buf
  1      SELECT LID, SID, Cnt, Limits, dense_rank() over (order by lid) as grp, Iter
  2      FROM (SELECT LID
  3                  ,SID
  4                  ,COUNT(*) OVER (PARTITION BY LID) Cnt
  5                  ,TRUNC(COUNT(*) OVER (PARTITION BY LID)/4)*4 Limits
  6                  ,row_number() over (partition by LID order by SID desc) iter
  7            FROM VW_TA
  8            WHERE C0 > 0 AND C1 > 0 AND C2 > 0 AND C3 > 0
  9            ORDER BY LID, SID DESC
10           ) a
11*     WHERE ITER <= LIMITS
SQL> /
       LID        SID        CNT     LIMITS        GRP       ITER
         1          6          6          4          1          1
         1          5          6          4          1          2
         1          4          6          4          1          3
         1          3          6          4          1          4
         3          7          7          4          2          1
         3          6          7          4          2          2
         3          5          7          4          2          3
         3          4          7          4          2          4
8 rows selected.
You already had the iteration part in your query, you just needed the Group number which is achieved using a dense_rank on the result.

Similar Messages

  • Pl/sql cursor and loop

    Hello.
    I need help creating a cursor and loop that will update a column based on data from another column. I keep getting the following errors. Any suggestions? These identifiers are valid tables in columns in my data base.
    SQL> DECLARE
    2
    3      CURSOR c1 IS
    4           SELECT SectionID, Coursename, StudentID, FinalGrade from Registration, Section, Grade WHERE registration.sectionid = grade.sectionid and registrationid.studentid = grade.studentid;
    5
    6      v_SectionID number(10);
    7      v_CourseName varchar(20);
    8      v_StudentID number(10);
    9      v_FinalGrade varchar2(5);
    10
    11 BEGIN
    12
    13      OPEN c1;
    14
    15      LOOP
    16           FETCH c1
    17           INTO v_SectionID, v_CourseName, v_StudentID, v_FinalGrade;
    18           EXIT WHEN c1%NOTFOUND;
    19
    20           update grade
    21
    22           SET FinalGrade = translate(substr(v_CourseName,-1,1),'ABCDEFGHIJKLMNOPQRSTUVWXYZ','AAAAAABBBBBCCCCCDDDDEEEEEE')
    23
    24           where Grade.StudentID = Registration.StudentID;
    25
    26      END LOOP;
    27 CLOSE c1;
    28 END;
    29 /
              SELECT SectionID, Coursename, StudentID, FinalGrade from Registration, Section, Grade WHERE registration.sectionid = grade.sectionid and registrationid.studentid = grade.studentid;
    ERROR at line 4:
    ORA-06550: line 4, column 140:
    PL/SQL: ORA-00904: "REGISTRATIONID"."STUDENTID": invalid identifier
    ORA-06550: line 4, column 3:
    PL/SQL: SQL Statement ignored
    ORA-06550: line 24, column 27:
    PL/SQL: ORA-00904: "REGISTRATION"."STUDENTID": invalid identifier
    ORA-06550: line 20, column 3:
    PL/SQL: SQL Statement ignored

    863737 wrote:
    I am taking a intro course online so I am trying to teach myself this. The most basic rule for designing and writing good Oracle code that will perform and will scale is to use SQL for what it is good at and using PL/SQL for what it is good at. And between the two, SQL is by far superior when it comes to crunching data in the database.
    The simple maxim is Maximize SQL. Minimize PL/SQL.
    What you want to do with that PL/SQL code can be done using SQL only. And since you are learning SQL and PL/SQL, it is very important that you learn the correct way to do this.
    Have a look at Oracle® Database SQL Language Reference guide.
    The update syntax supports:
    UPDATE <dml_expression_clause>
    Where this +<dml_expression_clause>+ is a SELECT statement (aka an in-line view) - that can contain joins.
    Simple example. You join tables t1 and t2 to identify the rows in t1 to update. The +<dml_expression_clause>+ will define this join. The actual update part (using the SET clause) will update the relevant rows in t1.
    This is also called an updatable view - though the +<dml_expression_clause>+ does not need to use an actual view.
    Have a look at AskTom for a discussion on this. Also note that you can also create a view and define an "instead-of" trigger on the view - this particular feature enhances the ability to update DML expressions - but is not a prerequisite.
    Note that there can be very significant performance degradation by NOT using an UPDATE on a +<dml_expression_clause>+ and instead coding that manually via PL/SQL.
    So do yourself a favour and learn the CORRECT way to resolve the type of UPDATE problem you have.

  • Report using cursors and loop

    Hi,
    can anybody suggest what kind of report and in what way I have to use if I want to write query using cursors within loops?
    Thanks!
    Karina.

    Hi,
    I found the solution. I just rewrite all cursors within one SQL statement and it works.
    Karina.

  • How to create store procedure using cursor, and looping condition with exce

    Hi,
    I am new in pl/sql development , please help me for follwoing
    1. I have select query by joining few tables which returns lets say 100 records.
    2. I want to insert records into another table(lets say table name is tbl_sale).
    3. If first record is inserted into tbl_sale,and for next record if value is same as first then update into tbl_sale else
    insert new row
    4. I want to achieve this using store procedure.
    Please help me how to do looping,how to use cursor and all other necessary thing to achieve this.

    DECLARE
       b   NUMBER;
    BEGIN
       UPDATE tbl_sale
          SET a = b
        WHERE a = 1;
       IF SQL%ROWCOUNT = 0
       THEN
          INSERT INTO tbl_sale
                      (a
               VALUES (b
       END IF;
    END;note : handle exceptions where ever needed
    Regards,
    friend
    Edited by: most wanted!!!! on Mar 18, 2013 12:06 AM

  • Why use cursor and for loop?

    Hi All
    So in general why would we use a cursor and a for loop to do update in a stored procedure?
    Why wouldnt we just use a single update statement ?
    is there compelling reason for using a cursor and a for loop: I am reading some code from a co-worker that the business logic for the select (set need to be updated) is complex but the update logic is simple (just set a flag to (0 or 1 or 2 or 3 or 4).
    But eventually the select come down to a key (row_id) so I re-write it using just a single sql statement.
    The size of the main table is about 2.6 to 3million rows
    Any thoughts on that??
    The code below I just do a google for cursor for update example in case for something to play with
    -Thanks for all your input
    create table f (a number, b varchar2(10));
    insert into f values (5,'five');
    insert into f values (6,'six');
    insert into f values (7,'seven');
    insert into f values (8,'eight');
    insert into f values (9,'nine');
    commit;
    create or replace procedure wco as
      cursor c_f is
        select a,b from f where length(b) = 5 for update;
        v_a f.a%type;
        v_b f.b%type;
    begin
      open c_f;
      loop
        fetch c_f into v_a, v_b;
        exit when c_f%notfound;
        update f set a=v_a*v_a where current of c_f;
      end loop;
      close c_f;
    end;
    exec wco;
    select * from f;
    drop table f;
    drop procedure wco;
    Joining multiple tables
    create table numbers_en (
      id_num  number        primary key,
      txt_num varchar2(10)
    insert into numbers_en values (1, 'one'  );
    insert into numbers_en values (2, 'two'  );
    insert into numbers_en values (3, 'three');
    insert into numbers_en values (4, 'four' );
    insert into numbers_en values (5, 'five' );
    insert into numbers_en values (6, 'six'  );
    create table lang (
       id_lang   char(2) primary key,
       txt_lang  varchar2(10)
    insert into lang values ('de', 'german');
    insert into lang values ('fr', 'french');
    insert into lang values ('it', 'italian');
    create table translations (
      id_num    references numbers_en,
      id_lang   references lang,
      txt_trans varchar2(10) not null
    insert into translations values (1, 'de', 'eins'   );
    insert into translations values (1, 'fr', 'un'     );
    insert into translations values (2, 'it', 'duo'    );
    insert into translations values (3, 'de', 'drei'   );
    insert into translations values (3, 'it', 'tre'    );
    insert into translations values (4, 'it', 'quattro');
    insert into translations values (6, 'de', 'sechs'  );
    insert into translations values (6, 'fr', 'six'    );
    declare
      cursor cur is
          select id_num,
                 txt_num,
                 id_lang,
                 txt_lang,
                 txt_trans
            from numbers_en join translations using(id_num)
                       left join lang         using(id_lang)
        for update of translations.txt_trans;
      rec cur%rowtype;
    begin
      for rec in cur loop
        dbms_output.put (
          to_char (rec.id_num         , '999') || ' - ' ||
          rpad    (rec.txt_num        ,   10 ) || ' - ' ||
          rpad(nvl(rec.txt_trans, ' '),   10 ) || ' - ' ||
                   rec.id_lang                 || ' - ' ||
          rpad    (rec.txt_lang       ,   10 )
        if mod(rec.id_num,2) = 0 then
          update translations set txt_trans = upper(txt_trans)
           where current of cur;
           dbms_output.put_line(' updated');
        else
          dbms_output.new_line;
        end if;
      end loop;
    end;
    /Edited by: xwo0owx on Apr 25, 2011 11:23 AM

    Adding my sixpence...
    PL/SQL is not that different from a SQL perspective than any other SQL client language like Java or C# or C/C++. PL/SQL simply integrates the 2 languages a heck of a lot better and far more transparent than the others. But make no mistake in that PL/SQL is also a "client" language from a SQL perspective. The (internal) calls PL/SQL make to the SQL engine, are the same (driver) calls made to the SQL engine when using Java and C and the others.
    So why a cursor and loops in PL/SQL? For the same reason you have cursors and loops in all these other SQL client languages. There are the occasion that you need to pull data from the SQL engine into the local language to perform some very funky and complex processing that is not possible using the SQL language.
    The danger is using client cursor loop processing as the norm - always pulling rows into the client language and crunching it there. This is not very performant. And pretty much impossible to scale. Developers in this case views the SQL language as a mere I/O interface for reading and writing rows. As they would use the standard file I/O read() and write() interface calls.
    Nothing could be further from the truth. SQL is a very advance and sophisticated data processing language. And it will always be faster than having to pull rows to a client language and process them there. However, SQL is not Turing complete. It is not the procedural type language that most other languages we use, are. For that reason there are things that we cannot do in SQL. And that should be the only reason for using the client language, like PL/SQL or the others, to perform row crunching using a client cursor loop.

  • Help with if statement in cursor and for loop to get output

    I have the following cursor and and want to use if else statement to get the output. The cursor is working fine. What i need help with is how to use and if else statement to only get the folderrsn that have not been updated in the last 30 days. If you look at the talbe below my select statement is showing folderrs 291631 was updated only 4 days ago and folderrsn 322160 was also updated 4 days ago.
    I do not want these two to appear in my result set. So i need to use if else so that my result only shows all folderrsn that havenot been updated in the last 30 days.
    Here is my cursor:
    /*Cursor for Email procedure. It is working Shows userid and the string
    You need to update these folders*/
    DECLARE
    a_user varchar2(200) := null;
    v_assigneduser varchar2(20);
    v_folderrsn varchar2(200);
    v_emailaddress varchar2(60);
    v_subject varchar2(200);
    Cursor c IS
    SELECT assigneduser, vu.emailaddress, f.folderrsn, trunc(f.indate) AS "IN DATE",
    MAX (trunc(fpa.attemptdate)) AS "LAST UPDATE",
    trunc(sysdate) - MAX (trunc(fpa.attemptdate)) AS "DAYS PAST"
    --MAX (TRUNC (fpa.attemptdate)) - TRUNC (f.indate) AS "NUMBER OF DAYS"
    FROM folder f, folderprocess fp, validuser vu, folderprocessattempt fpa
    WHERE f.foldertype = 'HJ'
    AND f.statuscode NOT IN (20, 40)
    AND f.folderrsn = fp.folderrsn
    AND fp.processrsn = fpa.processrsn
    AND vu.userid = fp.assigneduser
    AND vu.statuscode = 1
    GROUP BY assigneduser, vu.emailaddress, f.folderrsn, f.indate
    ORDER BY fp.assigneduser;
    BEGIN
    FOR c1 IN c LOOP
    IF (c1.assigneduser = v_assigneduser) THEN
    dbms_output.put_line(' ' || c1.folderrsn);
    else
    dbms_output.put(c1.assigneduser ||': ' || 'Overdue Folders:You need to update these folders: Folderrsn: '||c1.folderrsn);
    END IF;
    a_user := c1.assigneduser;
    v_assigneduser := c1.assigneduser;
    v_folderrsn := c1.folderrsn;
    v_emailaddress := c1.emailaddress;
    v_subject := 'Subject: Project for';
    END LOOP;
    END;
    The reason I have included the folowing table is that I want you to see the output from the select statement. that way you can help me do the if statement in the above cursor so that the result will look like this:
    emailaddress
    Subject: 'Project for ' || V_email || 'not updated in the last 30 days'
    v_folderrsn
    v_folderrsn
    etc
    [email protected]......
    Subject: 'Project for: ' Jim...'not updated in the last 30 days'
    284087
    292709
    [email protected].....
    Subject: 'Project for: ' Kim...'not updated in the last 30 days'
    185083
    190121
    190132
    190133
    190159
    190237
    284109
    286647
    294631
    322922
    [email protected]....
    Subject: 'Project for: Joe...'not updated in the last 30 days'
    183332
    183336
    [email protected]......
    Subject: 'Project for: Sam...'not updated in the last 30 days'
    183876
    183877
    183879
    183880
    183881
    183882
    183883
    183884
    183886
    183887
    183888
    This table is to shwo you the select statement output. I want to eliminnate the two days that that are less than 30 days since the last update in the last column.
    Assigneduser....Email.........Folderrsn...........indate.............maxattemptdate...days past since last update
    JIM.........      jim@ aol.com.... 284087.............     9/28/2006.......10/5/2006...........690
    JIM.........      jim@ aol.com.... 292709.............     3/20/2007.......3/28/2007............516
    KIM.........      kim@ aol.com.... 185083.............     8/31/2004.......2/9/2006.............     928
    KIM...........kim@ aol.com.... 190121.............     2/9/2006.........2/9/2006.............928
    KIM...........kim@ aol.com.... 190132.............     2/9/2006.........2/9/2006.............928
    KIM...........kim@ aol.com.... 190133.............     2/9/2006.........2/9/2006.............928
    KIM...........kim@ aol.com.... 190159.............     2/13/2006.......2/14/2006............923
    KIM...........kim@ aol.com.... 190237.............     2/23/2006.......2/23/2006............914
    KIM...........kim@ aol.com.... 284109.............     9/28/2006.......9/28/2006............697
    KIM...........kim@ aol.com.... 286647.............     11/7/2006.......12/5/2006............629
    KIM...........kim@ aol.com.... 294631.............     4/2/2007.........3/4/2008.............174
    KIM...........kim@ aol.com.... 322922.............     7/29/2008.......7/29/2008............27
    JOE...........joe@ aol.com.... 183332.............     1/28/2004.......4/23/2004............1585
    JOE...........joe@ aol.com.... 183336.............     1/28/2004.......3/9/2004.............1630
    SAM...........sam@ aol.com....183876.............3/5/2004.........3/8/2004.............1631
    SAM...........sam@ aol.com....183877.............3/5/2004.........3/8/2004.............1631
    SAM...........sam@ aol.com....183879.............3/5/2004.........3/8/2004.............1631
    SAM...........sam@ aol.com....183880.............3/5/2004.........3/8/2004.............1631
    SAM...........sam@ aol.com....183881.............3/5/2004.........3/8/2004.............1631
    SAM...........sam@ aol.com....183882.............3/5/2004.........3/8/2004.............1631
    SAM...........sam@ aol.com....183883.............3/5/2004.........3/8/2004.............1631
    SAM...........sam@ aol.com....183884.............3/5/2004.........3/8/2004............     1631
    SAM...........sam@ aol.com....183886.............3/5/2004.........3/8/2004............     1631
    SAM...........sam@ aol.com....183887.............3/5/2004.........3/8/2004............     1631
    SAM...........sam@ aol.com....183888.............3/5/2004.........3/8/2004............     1631
    PAT...........pat@ aol.com.....291630.............2/23/2007.......7/8/2008............     48
    PAT...........pat@ aol.com.....313990.............2/27/2008.......7/28/2008............28
    NED...........ned@ aol.com.....190681.............4/4/2006........8/10/2006............746
    NED...........ned@ aol.com......95467.............6/14/2006.......11/6/2006............658
    NED...........ned@ aol.com......286688.............11/8/2006.......10/3/2007............327
    NED...........ned@ aol.com.....291631.............2/23/2007.......8/21/2008............4
    NED...........ned@ aol.com.....292111.............3/7/2007.........2/26/2008............181
    NED...........ned@ aol.com.....292410.............3/15/2007.......7/22/2008............34
    NED...........ned@ aol.com.....299410.............6/27/2007.......2/27/2008............180
    NED...........ned@ aol.com.....303790.............9/19/2007.......9/19/2007............341
    NED...........ned@ aol.com.....304268.............9/24/2007.......3/3/2008............     175
    NED...........ned@ aol.com.....308228.............12/6/2007.......12/6/2007............263
    NED...........ned@ aol.com.....316689.............3/19/2008.......3/19/2008............159
    NED...........ned@ aol.com.....316789.............3/20/2008.......3/20/2008............158
    NED...........ned@ aol.com.....317528.............3/25/2008.......3/25/2008............153
    NED...........ned@ aol.com.....321476.............6/4/2008.........6/17/2008............69
    NED...........ned@ aol.com.....322160.............7/3/2008.........8/21/2008............4
    MOE...........moe@ aol.com.....184169.............4/5/2004.......12/5/2006............629
    [email protected]/27/2004.......3/8/2004............1631
    How do I incorporate a if else statement in the above cursor so the two days less than 30 days since last update are not returned. I do not want to send email if the project have been updated within the last 30 days.
    Edited by: user4653174 on Aug 25, 2008 2:40 PM

    analytical functions: http://download-west.oracle.com/docs/cd/B10501_01/server.920/a96540/functions2a.htm#81409
    CASE
    http://download.oracle.com/docs/cd/B10501_01/appdev.920/a96624/02_funds.htm#36899
    http://download.oracle.com/docs/cd/B10501_01/appdev.920/a96624/04_struc.htm#5997
    Incorporating either of these into your query should assist you in returning the desired results.

  • Ref Cursor and For Loop

    The query below will return values in the form of
    bu     seq     eligible
    22     2345     Y
    22     2345     N
    22     1288     N
    22     1458     Y
    22     1458     N
    22     1234     Y
    22     1333     N
    What I am trying to accomplish is to loop through the records returned.
    for each seq if there is a 'N' in the eligible column return no record for that seq
    eg seq 2345 has 'Y' and 'N' thus no record should be returned.
    seq 1234 has only a 'Y' then return the record
    seq 1333 has 'N' so return no record.
    How would I accomplish this with a ref Cursor and pass the values to the front end application.
    Procedure InvalidNOs(io_CURSOR OUT T_CURSOR)
         IS
              v_CURSOR T_CURSOR;
         BEGIN
    OPEN v_CURSOR FOR
    '     select bu, seq, eligible ' ||
    '     from (select bu, seq, po, tunit, tdollar,eligible,max(eligible) over () re ' ||
    '          from (select bu, seq, po, tunit, tdollar,eligible ' ||
    '          from ( ' ||
    '          select bu, seq, po, tunit, tdollar, eligible, sum(qty) qty, sum(price*qty) dollars ' ||
    '               from ' ||
    '               ( select /*+ use_nl(t,h,d,s) */ ' ||
    '               h.business_unit_id bu, h.edi_sequence_id seq, d.edi_det_sequ_id dseq, ' ||
    '                    s.edi_size_sequ_id sseq, h.po_number po, h.total_unit tUnit, h.total_amount tDollar, ' ||
    '                    s.quantity qty, s.unit_price price,' ||
    '               (select (case when count(*) = 0 then ''Y'' else ''N'' end) ' ||
    '          from sewn.NT_edii_po_det_error ' ||
    '          where edi_det_sequ_id = d.edi_det_sequ_id ' ||
    '               ) eligible ' ||
    '     from sewn.nt_edii_purchase_size s, sewn.nt_edii_purchase_det d, ' ||
    '     sewn.nt_edii_purchase_hdr h, sewn.nt_edii_param_temp t ' ||
    '     where h.business_unit_id = t.business_unit_id ' ||
    '     and h.edi_sequence_id = t.edi_sequence_id ' ||
    '     and h.business_unit_id = d.business_unit_id ' ||
    '     and h.edi_sequence_id = d.edi_sequence_id ' ||
    '     and d.business_unit_id = s.business_unit_id ' ||
    '     and d.edi_sequence_id = s.edi_sequence_id ' ||
    '     and d.edi_det_sequ_id = s.edi_det_sequ_id ' ||
    '     ) group by bu, seq, po, tunit, tdollar, eligible ' ||
    '     ) ' ||
    '     group by bu, seq, po, tunit, tdollar, eligible)) ';
              io_CURSOR := v_CURSOR;
    END     InvalidNOs;

    One remark why you should not use the assignment between ref cursor
    variables.
    (I remembered I saw already such thing in your code).
    Technically you can do it but it does not make sense and it can confuse your results.
    In the opposite to usual variables, when your assignment copies value
    from one variable to another, cursor variables are pointers to the memory.
    Because of this when you assign one cursor variable to another you just
    duplicate memory pointers. You don't copy result sets. What you do for
    one pointer is that you do for another and vice versa. They are the same.
    I think the below example is self-explained:
    SQL> /* usual variables */
    SQL> declare
      2   a number;
      3   b number;
      4  begin
      5   a := 1;
      6   b := a;
      7   a := a + 1;
      8   dbms_output.put_line('a = ' || a);
      9   dbms_output.put_line('b = ' || b);
    10  end;
    11  /
    a = 2
    b = 1
    PL/SQL procedure successfully completed.
    SQL> /* cursor variables */
    SQL> declare
      2   a sys_refcursor;
      3   b sys_refcursor;
      4  begin
      5   open a for select empno from emp;
      6   b := a;
      7   close b;
      8 
      9   /* next action is impossible - cursor already closed */
    10   /* a and b are the same ! */
    11   close a;
    12  end;
    13  /
    declare
    ERROR at line 1:
    ORA-01001: invalid cursor
    ORA-06512: at line 11
    SQL> declare
      2   a sys_refcursor;
      3   b sys_refcursor;
      4   vempno emp.empno%type;
      5 
      6  begin
      7   open a for select empno from emp;
      8   b := a;
      9 
    10   /* Fetch first row from a */
    11   fetch a into vempno;
    12   dbms_output.put_line(vempno);
    13 
    14   /* Fetch from b gives us SECOND row, not first -
    15      a and b are the SAME */
    16 
    17   fetch b into vempno;
    18   dbms_output.put_line(vempno);
    19 
    20 
    21  end;
    22  /
    7369
    7499
    PL/SQL procedure successfully completed.Rgds.
    Message was edited by:
    dnikiforov

  • How to add cursor and for loop

    PROCEDURE "TEST" is
    bala number;
    ins1 number;
    ins2 number;
    BEGIN
    select sum(bal) into bala from (select sum(acp.acp_totbal) bal,acp_instruid from cs_strmap_t map,cs_instru_strips strip,cs_acpos_bkp acp
    where c_int_instruid=c_srm_prncplinsid
    and c_srm_prncplinsid=acp_instruid
    and acp_acntnum!='SG030001'
    group by acp_instruid
    union
    select sum(acp.acp_totbal) bal,acp_instruid from cs_strmap_t map,cs_instru_strips strip,cs_acpos_bkp acp
    where c_int_instruid=c_srm_prncplinsid
    and acp_acntnum!='SG030001'
    and acp_instruid=c_srm_prntinsid
    group by acp_instruid)view1;
    dbms_output.put_line(bala);
    select acp_instruid into ins1 from cs_strmap_t map,cs_instru_strips strip,cs_acpos_bkp acp
    where c_int_instruid=c_srm_prncplinsid
    and c_srm_prncplinsid=acp_instruid
    and acp_acntnum='SG030001';
    dbms_output.put_line('principal'||ins1);
    select acp_instruid into ins2 from cs_strmap_t map,cs_instru_strips strip,cs_acpos_bkp acp
    where c_int_instruid=c_srm_prncplinsid
    and acp_acntnum='SG030001'
    and acp_instruid=c_srm_prntinsid;
    dbms_output.put_line('parent'||ins2);
    update cs_acpos_bkp
    set acp_totbal=-bala
    where acp_instruid=ins2
    and acp_acntnum='SG030001';
    END;
    i have written this code,i need to use cursor and for loops to get more than one rows and update also.
    if there are more than 1 rows in cs_strmap_t,then the procedure throws an error stating that it cannot take 2 rows.
    Edited by: 850836 on Apr 7, 2011 11:43 PM

    PROCEDURE "TEST" is
    bala number;
    ins1 number;
    ins2 number;
    CURSOR cur_1 IS
    select sum(bal) bala from (select sum(acp.acp_totbal) bal,acp_instruid from cs_strmap_t map,cs_instru_strips strip,cs_acpos_bkp acp
    where c_int_instruid=c_srm_prncplinsid
    and c_srm_prncplinsid=acp_instruid
    and acp_acntnum='SG030001'
    group by acp_instruid
    union
    select sum(acp.acp_totbal) bal,acp_instruid from cs_strmap_t map,cs_instru_strips strip,cs_acpos_bkp acp
    where c_int_instruid=c_srm_prncplinsid
    and acp_acntnum='SG030001'
    and acp_instruid=c_srm_prntinsid
    group by acp_instruid)view1;
    BEGIN
    select acp_instruid into ins1 from cs_strmap_t map,cs_instru_strips strip,cs_acpos_bkp acp
    where c_int_instruid=c_srm_prncplinsid
    and c_srm_prncplinsid=acp_instruid
    and acp_acntnum='SG030001';
    dbms_output.put_line('principal'||ins1);
    select acp_instruid into ins2 from cs_strmap_t map,cs_instru_strips strip,cs_acpos_bkp acp
    where c_int_instruid=c_srm_prncplinsid
    and acp_acntnum='SG030001'
    and acp_instruid=c_srm_prntinsid;
    dbms_output.put_line('parent'||ins2);
    for var_for in cur_1
    loop
    update cs_acpos_bkp
    set acp_totbal=var_for.bala
    where acp_instruid=ins2
    and acp_acntnum='SG030001'
    and abs(acp_totbal)>abs(bala);
    dbms_output.put_line(bala);
    end loop;
    END;
    i wrote the following procedure,but the balance is not getting updated.
    Getting this errors when there are more than 1 row in cs_strmap_t table
    ORA-01422: exact fetch returns more than requested number of rows
    ORA-06512: line 22
    ORA-06512: at line 2

  • How to optimize the select query that is executed in a cursor for loop?

    Hi Friends,
    I have executed the code below and clocked the times for every line of the code using DBMS_PROFILER.
    CREATE OR REPLACE PROCEDURE TEST
    AS
       p_file_id              NUMBER                                   := 151;
       v_shipper_ind          ah_item.shipper_ind%TYPE;
       v_sales_reserve_ind    ah_item.special_sales_reserve_ind%TYPE;
       v_location_indicator   ah_item.exe_location_ind%TYPE;
       CURSOR activity_c
       IS
          SELECT *
            FROM ah_activity_internal
           WHERE status_id = 30
             AND file_id = p_file_id;
    BEGIN
       DBMS_PROFILER.start_profiler ('TEST');
       FOR rec IN activity_c
       LOOP
          SELECT DISTINCT shipper_ind, special_sales_reserve_ind, exe_location_ind
                     INTO v_shipper_ind, v_sales_reserve_ind, v_location_indicator
                     FROM ah_item --464000 rows in this table
                    WHERE item_id_edw IN (
                             SELECT item_id_edw
                               FROM ah_item_xref --700000 rows in this table
                              WHERE item_code_cust = rec.item_code_cust
                                AND facility_num IN (
                                       SELECT facility_code
                                         FROM ah_chain_div_facility --17 rows in this table
                                        WHERE chain_id = ah_internal_data_pkg.get_chain_id (p_file_id)
                                          AND div_id = (SELECT div_id
                                                          FROM ah_div --8 rows in this table
                                                         WHERE division = rec.division)));
       END LOOP;
       DBMS_PROFILER.stop_profiler;
    EXCEPTION
       WHEN NO_DATA_FOUND
       THEN
          NULL;
       WHEN TOO_MANY_ROWS
       THEN
          NULL;
    END TEST;The SELECT query inside the cursor FOR LOOP took 773 seconds.
    I have tried using BULK COLLECT instead of cursor for loop but it did not help.
    When I took out the select query separately and executed with a sample value then it gave the results in a flash of second.
    All the tables have primary key indexes.
    Any ideas what can be done to make this code perform better?
    Thanks,
    Raj.

    As suggested I'd try merging the queries into a single SQL. You could also rewrite your IN clauses as JOINs and see if that helps, e.g.
    SELECT DISTINCT ai.shipper_ind, ai.special_sales_reserve_ind, ai.exe_location_ind
               INTO v_shipper_ind, v_sales_reserve_ind, v_location_indicator
               FROM ah_item ai, ah_item_xref aix, ah_chain_div_facility acdf, ah_div ad
              WHERE ai.item_id_edw = aix.item_id_edw
                AND aix.item_code_cust = rec.item_code_cust
                AND aix.facility_num = acdf.facility_code
                AND acdf.chain_id = ah_internal_data_pkg.get_chain_id (p_file_id)
                AND acdf.div_id = ad.div_id
                AND ad.division = rec.division;ALSO: You are calling ah_internal_data_pkg.get_chain_id (p_file_id) every time. Why not do it outside the loop and just use a variable in the inner query? That will prevent context switching and improve speed.
    Edited by: Dave Hemming on Dec 3, 2008 9:34 AM

  • Replace the following open/fetch/close statements with a cursor FOR loop

    Hi anyone could you please help me,
    I would like to replace the following open/fetch/close statements with a cursor FOR loop.
    Codes are:
    CREATE OR REPLACE PROCEDURE COMOES.orchid_shipment_interface IS
      -- get the com shipment header records
      CURSOR c_com_shphdr ( p_dwn_end_dt DATE ) IS
      SELECT custno client_id
           , plheadno plheadno
           , DECODE(carr_no,'FEDX',lading_no,'UPS',lading_no,carrier_pro_no) tracking_no
           , carr_no||'/'||carr_method carrier_id
           , plantid plant_id
           , carr_no
           , lading_no
           , del_custaddr ship_to_id
           , ol_type cfm_order_type
           , del_custno
           , shipterm    freight_terms
           , del_custattn attn_line
           , custaddr
        FROM com_plhead@com_pricing.world
       WHERE status = '9'
         AND (mod_dat) > p_dwn_end_dt;
      -- get the com shipment address records
      CURSOR c_com_shpadr (p_custaddr VARCHAR2) IS
      SELECT name1 addr_name
           , street1 addr_line1
           , street2 addr_line2
           , city city
           , state state_cd
           , zip zip
           , country country_cd
           , phone work_phone
           , email email1
        FROM com_address@com_pricing.world
       WHERE addr_id = p_custaddr;
      -- get the com shipment detail records
      CURSOR c_com_shpdtl ( p_plheadno NUMBER) IS
      SELECT pll.plheadno pllheadno
           , pll.pllineno ord_line_no
           , pll.ol_no erp_line_no
           , pll.ol_segno
           , pll.fg_id sku
           , pll.qty_shipped ship_qty
           , pll.ordno erp_ord_no
           FROM com_plline@com_pricing.world pll
       WHERE pll.plheadno = p_plheadno
         AND NOT EXISTS (SELECT '1'
                           FROM com_pkg_int_interface@com_pricing.world  cpi
                          WHERE pll.ordno = cpi.ordno
                            AND pll.ol_no = cpi.ol_no);
      -- type declaration
      -- type declaration of com table.
      TYPE t_com_shphdr IS TABLE OF c_com_shphdr%ROWTYPE INDEX BY BINARY_INTEGER;
      TYPE t_orchid_shphdr IS TABLE OF orchid_shipment_hdr_intf%ROWTYPE INDEX BY BINARY_INTEGER;
      TYPE t_com_shpadr IS TABLE OF c_com_shpadr%ROWTYPE INDEX BY BINARY_INTEGER;
      TYPE t_orchid_shpadr IS TABLE OF orchid_shipment_address_intf%ROWTYPE INDEX BY BINARY_INTEGER;
      TYPE t_com_shpdtl IS TABLE OF c_com_shpdtl%ROWTYPE INDEX BY BINARY_INTEGER;
      TYPE t_orchid_shpdtl IS TABLE OF orchid_shipment_dtl_intf%ROWTYPE INDEX BY BINARY_INTEGER;
      lv_company_code       com_customer.business_unit%TYPE;
      lv_erp_ord_no         com_plline.ordno%TYPE;
      lv_actual_ship_date   com_plline.confirm_date%TYPE;
      lv_po_no              com_oline.po_no%TYPE;
      lv_ord_date           com_oline.entrydate%TYPE;
      lv_hdr_batch_ctrl_no  download_batch_info.batch_ctrl_no%TYPE;
      lv_adr_batch_ctrl_no  download_batch_info.batch_ctrl_no%TYPE;
      lv_dtl_batch_ctrl_no  download_batch_info.batch_ctrl_no%TYPE;
      lv_sku_desc           com_salesitem.title%TYPE;
      lv_ord_qty            com_oldelseg.qty%TYPE;
      lr_com_shphdr    t_com_shphdr;
      lr_orchid_shphdr t_orchid_shphdr;
      lr_com_shpadr    t_com_shpadr;
      lr_orchid_shpadr t_orchid_shpadr;
      lr_com_shpdtl    t_com_shpdtl;
      lr_orchid_shpdtl t_orchid_shpdtl;
      -- variable declaration
      ln_shphdr_seq    NUMBER(10):= 0;
      ln_shpadr_seg    NUMBER(10):= 0;
      ln_shpdtl_seq    NUMBER(10):= 0;
      cnt              NUMBER(10):= 0;
      cnt1             NUMBER(10):= 0;
      ld_hdr_dwn_end_dt           download_batch_info.download_end_tstamp%TYPE;
      lc_hdr_dwn_status           download_batch_info.dwn_status%TYPE;
      ld_hdr_download_end_tstamp  DATE;
      ln_hdr_running_seq          NUMBER(10) := 0;
      ld_adr_dwn_end_dt           download_batch_info.download_end_tstamp%TYPE;
      lc_adr_dwn_status           download_batch_info.dwn_status%TYPE;
      ld_adr_download_end_tstamp  DATE;
      ln_adr_running_seg          NUMBER(10) := 0;
      ld_dtl_dwn_end_dt           download_batch_info.download_end_tstamp%TYPE;
      lc_dtl_dwn_status           download_batch_info.dwn_status%TYPE;
      ld_dtl_download_end_tstamp  DATE;
      ln_dtl_running_seq          NUMBER(10) := 0;
    BEGIN
      -- get the batch control number details from batch information table for shipment header
      BEGIN
        SELECT batch_ctrl_no
             , NVL(download_end_tstamp,TO_DATE('01/01/1980','MM/DD/YYYY'))
             , dwn_status
          INTO lv_hdr_batch_ctrl_no
             , ld_hdr_dwn_end_dt
             , lc_hdr_dwn_status
          FROM comoes.download_batch_info
         WHERE download_id = 'ORCHID_SHIPMENT_HDR_INTF';
      EXCEPTION
        WHEN NO_DATA_FOUND THEN
          DBMS_OUTPUT.PUT_LINE (' No Data Found for ORCHID_SHIPMENT_HDR_INTF in Download Batch Info table...!!!');
          RAISE;
        WHEN TOO_MANY_ROWS THEN
          DBMS_OUTPUT.PUT_LINE (' Too Many Rows found for ORCHID_SHIPMENT_HDR_INTF in Download Batch Info table...!!!');
          RAISE;
        WHEN OTHERS THEN
          DBMS_OUTPUT.PUT_LINE (' Following error occured while getting batch control number for ORCHID_SHIPMENT_HDR_INTF in Download Batch Info table...!!!'||SQLERRM);
          RAISE;
      END;
      -- get the batch control number details from batch information table for shipment address
      BEGIN
        SELECT batch_ctrl_no
             , NVL(download_end_tstamp,TO_DATE('01/01/1980','MM/DD/YYYY'))
             , dwn_status
          INTO lv_adr_batch_ctrl_no
             , ld_adr_dwn_end_dt
             , lc_adr_dwn_status
          FROM comoes.download_batch_info
         WHERE download_id = 'ORCHID_SHIPMENT_ADDRESS_INTF';
      EXCEPTION
        WHEN NO_DATA_FOUND THEN
          DBMS_OUTPUT.PUT_LINE (' No Data Found for ORCHID_SHIPMENT_ADDRESS_INTF in Download Batch Info table...!!!');
          RAISE;
        WHEN TOO_MANY_ROWS THEN
          DBMS_OUTPUT.PUT_LINE (' Too Many Rows found for ORCHID_SHIPMENT_ADDRESS_INTF in Download Batch Info table...!!!');
          RAISE;
        WHEN OTHERS THEN
          DBMS_OUTPUT.PUT_LINE (' Following error occured while getting batch control number for ORCHID_SHIPMENT_ADDRESS_INTF in Download Batch Info table...!!!'||SQLERRM);
          RAISE;
      END;
      -- get the batch control number details from batch information table for shipment details
      BEGIN
        SELECT batch_ctrl_no
             , NVL(download_end_tstamp,TO_DATE('01/01/1980','MM/DD/YYYY'))
             , dwn_status
          INTO lv_dtl_batch_ctrl_no
             , ld_dtl_dwn_end_dt
             , lc_dtl_dwn_status
          FROM download_batch_info
         WHERE download_id = 'ORCHID_SHIPMENT_DTL_INTF';
      EXCEPTION
        WHEN NO_DATA_FOUND THEN
          DBMS_OUTPUT.PUT_LINE (' No Data Found for ORCHID_SHIPMENT_DTL_INTF in Download Batch Info table...!!!');
          RAISE;
        WHEN TOO_MANY_ROWS THEN
          DBMS_OUTPUT.PUT_LINE (' Too Many Rows found for ORCHID_SHIPMENT_DTL_INTF in Download Batch Info table...!!!');
          RAISE;
        WHEN OTHERS THEN
          DBMS_OUTPUT.PUT_LINE (' Following error occured while getting batch control number for ORCHID_SHIPMENT_DTL_INTF in Download Batch Info table...!!!'||SQLERRM);
          RAISE;
      END;
      -- if previous run is not sucess then do nothing and return.
      OPEN c_com_shphdr ( ld_hdr_dwn_end_dt ) ;
      LOOP
        -- delete the collection for every cycle
        lr_com_shphdr.DELETE;
        lr_orchid_shphdr.DELETE;
        lr_com_shpadr.DELETE;
        lr_orchid_shpadr.DELETE;
        lr_com_shpdtl.DELETE;
        lr_orchid_shpdtl.DELETE;
        -- fetch the order header records to collection
        FETCH c_com_shphdr BULK COLLECT INTO lr_com_shphdr LIMIT 500;
        -- where there is no record in the collection the exit from the loop
        EXIT WHEN lr_com_shphdr.COUNT = 0;
        -- build your logic there to populate the data into order header collection.
          FOR i IN 1..lr_com_shphdr.COUNT
          LOOP
            -- accumulate header running sequence number
            ln_hdr_running_seq := ln_hdr_running_seq + 1;
            ln_shphdr_seq      := ln_hdr_running_seq;
             -- Get the business unit for the customer from com_customer
            BEGIN
              SELECT business_unit
                INTO lv_company_code
                FROM com_customer@com_pricing.world
               WHERE custno = lr_com_shphdr(i).del_custno;
            EXCEPTION
            WHEN OTHERS THEN
              lv_company_code := NULL;
            END;
            -- Get the ordno, confirm_date from COM_PLLINE
            BEGIN
            SELECT ordno
                 , confirm_date
              INTO lv_erp_ord_no
                 , lv_actual_ship_date
              FROM com_plline@com_pricing.world cpl
             WHERE cpl.plheadno = lr_com_shphdr(i).plheadno
               AND ROWNUM = 1;
            EXCEPTION
            WHEN OTHERS THEN
              lv_erp_ord_no       := NULL;
              lv_actual_ship_date := NULL;
            END;
            -- Get the po_no, Entry_date from COM_OLINE
            BEGIN
              SELECT po_no
                   , entrydate
                INTO lv_po_no
                   , lv_ord_date
                FROM com_oline@com_pricing.world col
               WHERE col.ordno = lv_erp_ord_no
                 AND ROWNUM = 1;
            EXCEPTION
            WHEN OTHERS THEN
              lv_po_no    := NULL;
              lv_ord_date := NULL;
            END;
            -- To assign the Bol Number from Lading Number
            IF lr_com_shphdr(i).carr_no NOT IN ('FEDX','UPS') THEN
               lr_orchid_shphdr(i).bol_no     := lr_com_shphdr(i).lading_no;
            ELSE
               lr_orchid_shphdr(i).bol_no     := NULL;
            END IF;
            -- For each order header get the Shipment Delivery Adderss
            OPEN c_com_shpadr ( lr_com_shphdr(i).custaddr);
            FETCH c_com_shpadr BULK COLLECT INTO lr_com_shpadr;
            -- where there is no record in the collection the exit from the loop
            EXIT WHEN lr_com_shpadr.COUNT = 0;
            -- biuld your logic here to populate the del address collection.
              FOR j IN 1..lr_com_shpadr.COUNT
              LOOP
                -- accumulate the loop count into temp variable, so that will through tell each set of order header.
                cnt := cnt + 1;
                -- accumolate the header running sequence number.
                ln_adr_running_seg := ln_adr_running_seg + 1;
                ln_shpadr_seg := ln_adr_running_seg;
                -- move the order address data into collection.
                lr_orchid_shpadr(cnt).client_id       := lr_com_shphdr(i).del_custno;
                lr_orchid_shpadr(cnt).ord_no          := lr_com_shphdr(i).plheadno;
                lr_orchid_shpadr(cnt).tracking_no     := lr_com_shphdr(i).tracking_no;
                lr_orchid_shpadr(cnt).addr_name       := lr_com_shpadr(j).addr_name;
                lr_orchid_shpadr(cnt).attn_line       := lr_com_shphdr(i).attn_line;
                lr_orchid_shpadr(cnt).addr_line1      := lr_com_shpadr(j).addr_line1;
                lr_orchid_shpadr(cnt).addr_line2      := lr_com_shpadr(j).addr_line2;
                lr_orchid_shpadr(cnt).addr_line3      := NULL;
                lr_orchid_shpadr(cnt).addr_line4      := NULL;
                lr_orchid_shpadr(cnt).addr_line5      := NULL;
                lr_orchid_shpadr(cnt).city            := lr_com_shpadr(j).city;
                lr_orchid_shpadr(cnt).state_cd        := lr_com_shpadr(j).state_cd;
                lr_orchid_shpadr(cnt).zip             := lr_com_shpadr(j).zip;
                lr_orchid_shpadr(cnt).zip_ext         := NULL;
                lr_orchid_shpadr(cnt).country_cd      := lr_com_shpadr(j).country_cd;
                lr_orchid_shpadr(cnt).tax_geo_cd      := NULL;
                lr_orchid_shpadr(cnt).work_phone      := lr_com_shpadr(j).work_phone;
                lr_orchid_shpadr(cnt).email1          := lr_com_shpadr(j).email1;
                lr_orchid_shpadr(cnt).cre_dat         := SYSDATE;
                lr_orchid_shpadr(cnt).cre_usr         := USER;
                lr_orchid_shpadr(cnt).batch_ctrl_no   := lv_adr_batch_ctrl_no;
              END LOOP;
            CLOSE c_com_shpadr;
            -- For each order header get the order detail/delivery segment data
            OPEN c_com_shpdtl ( lr_com_shphdr(i).plheadno );
            FETCH c_com_shpdtl BULK COLLECT INTO lr_com_shpdtl;
            -- where there is no record in the collection the exit from the loop
            EXIT WHEN lr_com_shpdtl.COUNT = 0;
            -- build your logic here to populate the order detail collection
              FOR k IN 1..lr_com_shpdtl.COUNT
              LOOP
                -- accumulate the loop count into a temp variable, so that will through till each set of Order Header.
                cnt1 := cnt1 + 1;
                -- accumulate header running sequence number
                ln_dtl_running_seq := ln_dtl_running_seq + 1;
                ln_shpdtl_seq := ln_dtl_running_seq;
                -- Get Quantity for the delvery from delevery segment table.
                BEGIN
                  SELECT NVL(Qty,0)
                    INTO lv_ord_qty
                    FROM com_oldelseg@com_pricing.world cds
                   WHERE cds.ordno = lr_com_shpdtl(k).erp_ord_no
                     AND cds.ol_no = lr_com_shpdtl(k).erp_line_no
                     AND cds.ol_segno = lr_com_shpdtl(k).ol_segno;
                EXCEPTION
                  WHEN OTHERS THEN
                    lv_ord_qty := NULL;
                END;
                -- Get Title for the salesitem from the salesitem table.
                BEGIN
                  SELECT Title
                    INTO lv_sku_desc
                    FROM com_salesitem@com_pricing.world cs
                   WHERE cs.fg_id = lr_com_shpdtl(k).sku;
                EXCEPTION
                  WHEN OTHERS THEN
                    lv_sku_desc := NULL;
                END;
                -- move the Order detail data into collection
                lr_orchid_shpdtl(cnt1).client_id         := lr_com_shphdr(i).client_id;
                lr_orchid_shpdtl(cnt1).ord_no            := lr_com_shphdr(i).plheadno;
                lr_orchid_shpdtl(cnt1).ord_line_no       := lr_com_shpdtl(k).ord_line_no;
                lr_orchid_shpdtl(cnt1).erp_line_no       := lr_com_shpdtl(k).erp_line_no;
                lr_orchid_shpdtl(cnt1).sku               := lr_com_shpdtl(k).sku;
                lr_orchid_shpdtl(cnt1).tracking_no       := lr_com_shphdr(i).tracking_no;
                lr_orchid_shpdtl(cnt1).container_no      := NULL;
                lr_orchid_shpdtl(cnt1).ord_qty           := lv_ord_qty;
                lr_orchid_shpdtl(cnt1).ship_qty          := lr_com_shpdtl(k).ship_qty;
                lr_orchid_shpdtl(cnt1).price_point       := NULL;
                lr_orchid_shpdtl(cnt1).pick_invoice_no   := NULL;
                lr_orchid_shpdtl(cnt1).cancel_qty        := NULL;
                lr_orchid_shpdtl(cnt1).bldg_id           := NULL;                              --lr_com_shpdtl(k).bldg_id;
                lr_orchid_shpdtl(cnt1).sku_company       := NULL;                              --lr_com_shpdtl(k).sku_company;
                lr_orchid_shpdtl(cnt1).sku_desc          := lv_sku_desc;
                lr_orchid_shpdtl(cnt1).icc_cd1           := NULL;                              --lr_com_shpdtl(k).icc_cd1;
                lr_orchid_shpdtl(cnt1).erp_ord_no        := lr_com_shpdtl(k).erp_ord_no;
                lr_orchid_shpdtl(cnt1).cre_dat           := SYSDATE;
                lr_orchid_shpdtl(cnt1).cre_usr           := USER;
                lr_orchid_shpdtl(cnt1).batch_ctrl_no     := lv_dtl_batch_ctrl_no;
              END LOOP;
            CLOSE c_com_shpdtl;
            -- build the logic to populate Order Header
            lr_orchid_shphdr(i).client_id              := lr_com_shphdr(i).client_id;
            lr_orchid_shphdr(i).ord_no                 := lr_com_shphdr(i).plheadno;
            lr_orchid_shphdr(i).tracking_no            := lr_com_shphdr(i).tracking_no;
            lr_orchid_shphdr(i).container_no           := NULL;                            -- container number is not maintained in COM
            lr_orchid_shphdr(i).carrier_id             := lr_com_shphdr(i).carrier_id;
            lr_orchid_shphdr(i).plant_id               := lr_com_shphdr(i).plant_id;
            lr_orchid_shphdr(i).erp_ord_no             := lv_erp_ord_no;
            lr_orchid_shphdr(i).erp_ord_no2            := NULL;
            lr_orchid_shphdr(i).po_no                  := lv_po_no;
            lr_orchid_shphdr(i).ship_to_id             := lr_com_shphdr(i).ship_to_id;
            lr_orchid_shphdr(i).ship_to_addr_id        := lr_com_shphdr(i).custaddr;
            lr_orchid_shphdr(i).scac                   := NULL;                             --lr_com_shphdr(i).scac;
            lr_orchid_shphdr(i).actual_ship_date       := lv_actual_ship_date;
            lr_orchid_shphdr(i).cfm_order_type         := lr_com_shphdr(i).cfm_order_type;
            lr_orchid_shphdr(i).company_code           := lv_company_code;
            lr_orchid_shphdr(i).no_of_order_lines      := NULL;                             --lr_com_shphdr(i).no_of_order_lines;
            lr_orchid_shphdr(i).pick_invoice_no        := NULL;
            lr_orchid_shphdr(i).ord_date               := lv_ord_date;
            lr_orchid_shphdr(i).orig_tender_date       := NULL;
            lr_orchid_shphdr(i).orig_delv_date         := NULL;
            lr_orchid_shphdr(i).delivery_flag          := NULL;
            lr_orchid_shphdr(i).delv_date_from         := NULL;
            lr_orchid_shphdr(i).delv_date_to           := NULL;
            lr_orchid_shphdr(i).orig_carr_cd           := NULL;
            lr_orchid_shphdr(i).routing_comment        := NULL;
            lr_orchid_shphdr(i).segment_type           := NULL;
            lr_orchid_shphdr(i).back_order_flag        := NULL;
            lr_orchid_shphdr(i).addr_override_flag     := NULL;
            lr_orchid_shphdr(i).fmx_assigned_carr      := NULL;
            lr_orchid_shphdr(i).fmx_assigned_ship_date := NULL;
            lr_orchid_shphdr(i).fmx_assigned_delv_date := NULL;
            lr_orchid_shphdr(i).freight_terms          := lr_com_shphdr(i).freight_terms;
            lr_orchid_shphdr(i).fmx_load_id            := NULL;
            lr_orchid_shphdr(i).asn_type               := NULL;
            lr_orchid_shphdr(i).icc_cd1                := NULL;                             --lr_com_shphdr(i).icc_cd1;
            lr_orchid_shphdr(i).trans_type             := NULL;
            lr_orchid_shphdr(i).ref_no1                := NULL;
            lr_orchid_shphdr(i).ref_no2                := NULL;
            lr_orchid_shphdr(i).ref_no3                := NULL;
            lr_orchid_shphdr(i).ref_no4                := NULL;
            lr_orchid_shphdr(i).cre_dat                := SYSDATE;
            lr_orchid_shphdr(i).cre_usr                := USER;
            lr_orchid_shphdr(i).batch_ctrl_no          := lv_hdr_batch_ctrl_no;
            -- logic to get total boxes and weight.
            BEGIN
              SELECT SUM(no_cartons), SUM(weight)
                INTO lr_orchid_shphdr(i).total_boxes
                   , lr_orchid_shphdr(i).weight
                FROM com_plline@com_pricing.world pll
               WHERE pll.plheadno = lr_com_shphdr(i).plheadno;
            EXCEPTION
             WHEN OTHERS THEN
                lr_orchid_shphdr(i).total_boxes := NULL;
                lr_orchid_shphdr(i).weight      := NULL;
            END;
          END LOOP;
        -- initialize the variables for next loop cycle.
        cnt := 0;
        cnt1 := 0;
        -- populate the shipment header interface table.
        FOR x IN 1..lr_orchid_shphdr.COUNT
        LOOP
          ld_hdr_download_end_tstamp := lr_orchid_shphdr(x).cre_dat;
          INSERT INTO orchid_shipment_hdr_intf
                    (record_qualifier
                    ,client_id
                    ,ord_no
                    ,tracking_no
                    ,container_no
                    ,bol_no
                    ,carrier_id
                    ,plant_id
                    ,erp_ord_no
                    ,erp_ord_no2
                    ,po_no
                    ,ship_to_id
                    ,ship_to_addr_id
                    ,scac
                    ,actual_ship_date
                    ,cfm_order_type
                    ,company_code
                    ,no_of_order_lines
                    ,pick_invoice_no
                    ,total_boxes
                    ,weight
                    ,ord_date
                    ,orig_tender_date
                    ,orig_delv_date
                    ,delivery_flag
                    ,delv_date_from
                    ,delv_date_to
                    ,orig_carr_cd
                    ,routing_comment
                    ,segment_type
                    ,back_order_flag
                    ,addr_override_flag
                    ,fmx_assigned_carr
                    ,fmx_assigned_ship_date
                    ,fmx_assigned_delv_date
                    ,freight_terms
                    ,fmx_load_id
                    ,asn_type
                    ,upl_status
                    ,icc_cd1
                    ,trans_type
                    ,ref_no1
                    ,ref_no2
                    ,ref_no3
                    ,ref_no4
                    ,cre_dat
                    ,cre_usr
                    ,batch_ctrl_no)
            VALUES
                    ( 10
                    ,lr_orchid_shphdr(x).client_id
                    ,lr_orchid_shphdr(x).ord_no
                    ,lr_orchid_shphdr(x).tracking_no
                    ,lr_orchid_shphdr(x).container_no
                    ,lr_orchid_shphdr(x).bol_no
                    ,lr_orchid_shphdr(x).carrier_id
                    ,lr_orchid_shphdr(x).plant_id
                    ,lr_orchid_shphdr(x).erp_ord_no
                    ,lr_orchid_shphdr(x).erp_ord_no2
                    ,lr_orchid_shphdr(x).po_no
                    ,lr_orchid_shphdr(x).ship_to_id
                    ,lr_orchid_shphdr(x).ship_to_addr_id
                    ,lr_orchid_shphdr(x).scac
                    ,lr_orchid_shphdr(x).actual_ship_date
                    ,lr_orchid_shphdr(x).cfm_order_type
                    ,lr_orchid_shphdr(x).company_code
                    ,lr_orchid_shphdr(x).no_of_order_lines
                    ,lr_orchid_shphdr(x).pick_invoice_no
                    ,lr_orchid_shphdr(x).total_boxes
                    ,lr_orchid_shphdr(x).weight
                    ,lr_orchid_shphdr(x).ord_date
                    ,lr_orchid_shphdr(x).orig_tender_date
                    ,lr_orchid_shphdr(x).orig_delv_date
                    ,lr_orchid_shphdr(x).delivery_flag
                    ,lr_orchid_shphdr(x).delv_date_from
                    ,lr_orchid_shphdr(x).delv_date_to
                    ,lr_orchid_shphdr(x).orig_carr_cd
                    ,lr_orchid_shphdr(x).routing_comment
                    ,lr_orchid_shphdr(x).segment_type
                    ,lr_orchid_shphdr(x).back_order_flag
                    ,lr_orchid_shphdr(x).addr_override_flag
                    ,lr_orchid_shphdr(x).fmx_assigned_carr
                    ,lr_orchid_shphdr(x).fmx_assigned_ship_date
                    ,lr_orchid_shphdr(x).fmx_assigned_delv_date
                    ,lr_orchid_shphdr(x).freight_terms
                    ,lr_orchid_shphdr(x).fmx_load_id
                    ,lr_orchid_shphdr(x).asn_type
                    ,00
                    ,lr_orchid_shphdr(x).icc_cd1
                    ,lr_orchid_shphdr(x).trans_type
                    ,lr_orchid_shphdr(x).ref_no1
                    ,lr_orchid_shphdr(x).ref_no2
                    ,lr_orchid_shphdr(x).ref_no3
                    ,lr_orchid_shphdr(x).ref_no4
                    ,lr_orchid_shphdr(x).cre_dat
                    ,lr_orchid_shphdr(x).cre_usr
                    ,lr_orchid_shphdr(x).batch_ctrl_no);
        END LOOP;
        -- populate the shipment address interface table.
        FOR y IN 1..lr_orchid_shpadr.COUNT
        LOOP
          ld_adr_download_end_tstamp := lr_orchid_shpadr(y).cre_dat;
          INSERT INTO orchid_shipment_address_intf
                      ( record_qualifier
                      , client_id
                      , ord_no
                      , tracking_no
                      , addr_name
                      , attn_line
                      , addr_line1
                      , addr_line2
                      , addr_line3
                      , addr_line4
                      , addr_line5
                      , city
                      , state_cd
                      , zip
                      , zip_ext
                      , country_cd
                      , tax_geo_cd
                      , work_phone
                      , email1
                      , cre_dat
                      , cre_usr
                      , batch_ctrl_no)
               VALUES ( 14
                      , lr_orchid_shpadr(y).client_id
                      , lr_orchid_shpadr(y).ord_no
                      , lr_orchid_shpadr(y).tracking_no
                      , lr_orchid_shpadr(y).addr_name
                      , lr_orchid_shpadr(y).attn_line
                      , lr_orchid_shpadr(y).addr_line1
                      , lr_orchid_shpadr(y).addr_line2
                      , lr_orchid_shpadr(y).addr_line3
                      , lr_orchid_shpadr(y).addr_line4
                      , lr_orchid_shpadr(y).addr_line5
                      , lr_orchid_shpadr(y).city
                      , lr_orchid_shpadr(y).state_cd
                      , lr_orchid_shpadr(y).zip
                      , lr_orchid_shpadr(y).zip_ext
                      , lr_orchid_shpadr(y).country_cd
                      , lr_orchid_shpadr(y).tax_geo_cd
                      , lr_orchid_shpadr(y).work_phone
                      , lr_orchid_shpadr(y).email1
                      , lr_orchid_shpadr(y).cre_dat
                      , lr_orchid_shpadr(y).cre_usr
                      , lr_orchid_shpadr(y).batch_ctrl_no);
        END LOOP;
        -- populate the shipment detail interface table.
        FOR z IN 1..lr_orchid_shpdtl.COUNT
        LOOP
          ld_dtl_download_end_tstamp := lr_orchid_shpdtl(z).cre_dat;
          INSERT INTO orchid_shipment_dtl_intf
                      ( record_qualifier
                      , client_id
                      , ord_no
                      , ord_line_no
                      , erp_line_no
                      , sku
                      , tracking_no
                      , container_no
                      , ord_qty
                      , ship_qty
                      , price_point
                      , pick_invoice_no
                      , cancel_qty
                      , bldg_id
                      , sku_company
                      , sku_desc
                      , icc_cd1
                      , erp_ord_no
                      , cre_dat
                      , cre_usr
                      , batch_ctrl_no)
               VALUES ( 20
                      , lr_orchid_shpdtl(z).client_id
                      , lr_orchid_shpdtl(z).ord_no
                      , lr_orchid_shpdtl(z).ord_line_no
                      , lr_orchid_shpdtl(z).erp_line_no
                      , lr_orchid_shpdtl(z).sku
                      , lr_orchid_shpdtl(z).tracking_no
                      , lr_orchid_shpdtl(z).container_no
                      , lr_orchid_shpdtl(z).ord_qty
                      , lr_orchid_shpdtl(z).ship_qty
                      , lr_orchid_shpdtl(z).price_point
                      , lr_orchid_shpdtl(z).pick_invoice_no
                      , lr_orchid_shpdtl(z).cancel_qty
                      , lr_orchid_shpdtl(z).bldg_id
                      , lr_orchid_shpdtl(z).sku_company
                      , lr_orchid_shpdtl(z).sku_desc
                      , lr_orchid_shpdtl(z).icc_cd1
                      , lr_orchid_shpdtl(z).erp_ord_no
                      , lr_orchid_shpdtl(z).cre_dat
                      , lr_orchid_shpdtl(z).cre_usr
                      , lr_orchid_shpdtl(z).batch_ctrl_no);
        END LOOP;
        COMMIT;
      END LOOP;
      CLOSE c_com_shphdr;
      -- set the status to success
      UPDATE comoes.download_batch_info
         SET batch_ctrl_no = orchid_plhead_btch_ctrl_seq.NEXTVAL
           , dwn_status = '90'
           , download_end_tstamp = NVL(ld_hdr_download_end_tstamp,SYSDATE)
       WHERE download_id = 'ORCHID_SHIPMENT_HDR_INTF'
         AND batch_ctrl_no = lv_hdr_batch_ctrl_no;
      UPDATE comoes.download_batch_info
         SET batch_ctrl_no = orchid_address_btch_ctrl_seq.NEXTVAL
           , dwn_status = '90'
           , download_end_tstamp = NVL(ld_hdr_download_end_tstamp,SYSDATE)
       WHERE download_id = 'ORCHID_SHIPMENT_ADDRESS_INTF'
         AND batch_ctrl_no = lv_adr_batch_ctrl_no;
      UPDATE comoes.download_batch_info
         SET batch_ctrl_no = orchid_plline_btch_ctrl_seq.NEXTVAL
           , dwn_status = '90'
           , download_end_tstamp = NVL(ld_dtl_download_end_tstamp,SYSDATE)
       WHERE download_id = 'ORCHID_SHIPMENT_DTL_INTF'
         AND batch_ctrl_no = lv_dtl_batch_ctrl_no;
      -- Update the download status to success in the interface table.
      -- Shipment Header
      COMMIT;
    EXCEPTION
      WHEN OTHERS THEN
        -- load is not sucess then set the status to fail
        UPDATE comoes.download_batch_info
           SET dwn_status = '99'
         WHERE download_id = 'ORCHID_SHIPMENT_HDR_INTF'
           AND batch_ctrl_no = lv_hdr_batch_ctrl_no;
        UPDATE comoes.download_batch_info
           SET dwn_status = '99'
         WHERE download_id = 'ORCHID_SHIPMENT_ADDRESS_INTF'
           AND batch_ctrl_no = lv_adr_batch_ctrl_no;
        UPDATE comoes.download_batch_info
           SET dwn_status = '99'
         WHERE download_id = 'ORCHID_SHIPMENT_DTL_INTF'
           AND batch_ctrl_no = lv_dtl_batch_ctrl_no;
        COMMIT;
        DBMS_OUTPUT.PUT_LINE('Following error occured while executing ORCHID_SHIPMENT_INTF procedure...!!!'||SQLERRM);
        RAISE;
    END orchid_shipment_interface;Edited by: BluShadow on 03-Aug-2011 13:28
    added {noformat}{noformat} tags. Please read {message:id=9360002} to learn to do this yourself.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                &nb

    Please read the Forum FAQ on how to ask a question, particularly how to format code
    SQL and PL/SQL FAQ
    SQL and PL/SQL FAQ
    WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE (' Following error occured while getting batch control number for ORCHID_SHIPMENT_HDR_INTF in Download Batch Info table...!!!'||SQLERRM);
    RAISE;http://tkyte.blogspot.com/2008/01/why-do-people-do-this.html

  • Cursor and Update rows based on value/date

    SQL Server 2012
    Microsoft SQL Server Management Studio
    11.0.3128.0
    Microsoft Analysis Services Client Tools
    11.0.3128.0
    Microsoft Data Access Components (MDAC)
    6.1.7601.17514
    Microsoft MSXML 3.0 4.0 5.0 6.0 
    Microsoft Internet Explorer
    9.11.9600.16518
    Microsoft .NET Framework
    4.0.30319.18408
    Operating System
    6.1.7601
    The objective of this is to test the Cursor and use it on a production environment after this is fixed. What I would like to do is update rows in a column i duplicated originally called 'HiredDate' from AdventureWorks2012 HumanResources.Employee table. I
    made a duplicate column called 'DateToChange' and would like to change it based on a date I have picked, which returns normally 2 results (i.e. date is '04/07/2003'). The code runs but will not change both dates. It did run however with an error but changed
    only 1 of the 2 rows because it said ['nothing available in next fetch'].
    The code to add the columns and perform the query to get the results I am running this against:
    -- ADD column 'DateToChange'
    ALTER TABLE [HumanResources].[Employee] ADD DateToChange Date NOT NULL;
    -- Copy 'HireDate' data to 'DateToChange'
    UPDATE HumanResources.Employee SET DateToChange = HireDate;
    -- Change 'DateToChange' to NOT NULL
    ALTER TABLE [HumanResources].[Employee] ALTER COLUMN DateToChange Date NOT NULL;
    SELECT BusinessEntityID,HireDate, CONVERT( char(10),[DateToChange],101) AS [Formatted Hire Date]
    FROM HumanResources.Employee
    WHERE [DateToChange] = '04/07/2003';
    Code:
    USE AdventureWorks2012;
    GO
    -- Holds output of the CURSOR
    DECLARE @EmployeeID INT
    DECLARE @HiredDate DATETIME
    DECLARE @HiredModified DATETIME
    DECLARE @ChangeDateTo DATETIME
    --Declare cursor
    -- SCROLL CURSOR ALLOWS "for extra options" to pul multiple records: i.e. PRIOR, ABSOLUTE ##, RELATIVE ##
    DECLARE TestCursor CURSOR SCROLL FOR
    -- SELECT statement of what records going to be used by CURSOR
    -- Assign the query to the cursor.
    SELECT /*HumanResources.Employee.BusinessEntityID, HumanResources.Employee.HireDate,*/ CONVERT( char(10),[DateToChange],101) AS [Formatted Hire Date]
    FROM HumanResources.Employee
    WHERE DateToChange = '01/01/1901'
    /*ORDER BY HireDate DESC*/ FOR UPDATE OF [DateToChange];
    -- Initiate CURSOR and load records
    OPEN TestCursor
    -- Get first row from query
    FETCH NEXT FROM TestCursor
    INTO @HiredModified
    -- Logic to tell the Cursor while "@@FETCH_STATUS" 0 the cursor has successfully fetched the next record.
    WHILE (@@FETCH_STATUS = 0 AND @@CURSOR_ROWS = -1)
    BEGIN
    FETCH NEXT FROM TestCursor
    IF (@HiredModified = '04/07/2003')/*05/18/2006*/
    -- Sets @HiredModifiedDate data to use for the change
    SELECT @ChangeDateTo = '01/01/1901'
    UPDATE HumanResources.Employee
    SET [DateToChange] = @ChangeDateTo --'01/01/1901'
    FROM HumanResources.Employee
    WHERE CURRENT OF TestCursor;
    END
    -- CLOSE CURSOR
    CLOSE TestCursor;
    -- Remove any references held by cursor
    DEALLOCATE TestCursor;
    GO
    This query is run successfully but it does not produce the desired results to change the dates
    04/07/2003 to 01/01/1901.
    I would like the query to essentially be able to run the initial select statement, and then update and iterate through the returned results while replacing the necessary column in each row.
    I am also open to changes or a different design all together. 
    For this query I need:
    1. To narrow the initial set of information
    2. Check if the information returned, in particular a date, is before [i.e. this current month minus 12 months or
    12 months before current month]
    3. Next replace the dates with the needed date
    [Haven't written this out yet but it will need to be done]
    4. After all this is done I will then need to update a column on each row:
    if the 'date' is within 12 months to 12 months from the date checked
    NOTE: I am new to TSQL and have only been doing this for a few days, but I will understand or read up on what is explained if given enough information. Thank you in advance for anyone who may be able to help.

    The first thing you need to do is forget about cursors.  Those are rarely needed.  Instead you need to learn the basics of the tsql language and how to work with data in sets.  For starters, your looping logic is incorrect.  You open
    the cursur and immediately fetch the first row.  You enter the loop and the first thing in the loop does what?  Fetches another row.  That means you have "lost" the values from the first row fetched.  You also do not test the success of
    that fetch but immediately try to use the fetched value.  In addition, your cursor includes the condition "DateToChange = '01/01/1901' " - by extension you only select rows where HireDate is Jan 1 1901.  So the value fetched into @HiredModified will
    never be anything different - it will always be Jan 1 1901.  The IF logic inside your loop will always evaluate to FALSE.  
    But forget all that.  In words, tell us what you are trying to do.  It seems that you intend to add a new column to a table - one that is not null (ultimately) and is set to a particular value based on some criteria.  Since you intend the
    column to be not null, it is simpler to just add the column as not null with a default.  Because you are adding the column, the assumption is that you need to set the appropriate value for EVERY row in the table so the actual default value can be anything.
     Given the bogosity of the 1/1/1901 value, why not use this as your default and then set the column based on the Hiredate afterwards.  Simply follow the alter table statement with an update statement.  I don't really understand what your logic
    or goal is, but perhaps that will come with a better description.  In short: 
    alter table xxx add DateToChange date default '19010101'
    update xxx set DateToChange = HireDate where [some unclear condition]
    Lastly, you should consider wrapping everything you do in a transaction so that you recover from any errors.  In a production system, you should consider making a backup immediately before you do anything - strongly consider and have a good reason not
    to do so if that is your choice (and have a recovery plan just in case). 

  • Commit after every three UPDATEs in CURSOR FOR loop

    DB Version: 11g
    I know that experts in here despise the concept of COMMITing inside loop.
    But most of the UPDATEs being fired by the code below are updating around 1 million records and it is breaking our UNDO tablespace.
    begin
    for rec in
          (select owner,table_name,column_name 
          from dba_tab_cols where column_name like 'ABCD%' and owner = p_schema_name)
          loop
            begin
            execute immediate 'update '||rec.owner||'.'||rec.table_name||' set '||rec.column_name|| ' = '''||rec.owner||'';
            end;
          end loop;
    end;We are not expecting ORA-01555 error as these are just batch updates.
    I was thinking of implementing something like
    FOR i IN 1..myarray.count
    LOOP
                             DBMS_OUTPUT.PUT_LINE('event_key at' || i || ' is: ' || myarray(i));
                             INSERT INTO emp
                             empid,
                             event_id,
                             dept,
                             event_key
                             VALUES
                             v_empid,
                             3423,
                             p_dept,
                             myarray(i)
                             if(MOD(i, p_CommitFreq) = 0)  --- When the loop counter becomes fully divisible by p_commit_frequency, it COMMITs
                             then
                                       commit;
                             end if;
    END LOOP;(Found from an OTN thread)
    But i don't know how to access the loop counter value in a CURSOR FOR loop.

    To be fair, what is really despised is code that takes an operation that could have been performed in a single SQL statement and steps through it in the slowest possible way, committing pointlessly as it goes along (exactly like the example you found). Your original version doesn't do that - it looks more like some sort of one-off migration where you have to set every value of every column that matches some naming standard pattern to a constant. If that's the case, and if there are huge volumes involved and you can't simply add a bit more undo, then I don't see much wrong with committing after each update, especially if you track how far you've got so you can restart cleanly if it fails.
    If you really want an incrementing counter in an unnamed cursor, apart from the explicit variable others have suggested, you could add rownum to the cursor (alias it to something that isn't an Oracle keyword), although it could complicate the ORDER BY that you might be considering for the restart logic. You could have that instead of the redundant 'owner' column in your example which is always the same as the constant p_schema_name.
    Another approach would be to keep track of SQL%ROWCOUNT after each update by adding it to a variable, and commit when the total number of rows updated so far reaches, say, a million.
    Could the generated statement use a WHERE clause, or does it really have to update every row in every table it finds?
    Could there be more than one column to update per table? If so it might be worth generating one multi-column update statement per table, although it'll complicate things a bit.
    btw you don't need the inner 'begin' and 'end' keywords, and whoever supplied the MOD example you found should know that three or four spaces usually make a good indent and you don't need brackets around IF conditions.

  • "FOR REC IN CURSOR(PARAMETERS) LOOP" command does not work. Why?

    Hi to all.
    It's a pleasure to receive your help.
    In "FOR REC IN CURSOR(PARAMETERS) LOOP" command although the query return value does not enter the loop.
    Sounds simple, but I'm not seeing the flaw...
    Suggestions?
    Version: Oracle Database 10g Enterprise Edition Release 10.2.0.4.0
    Thank in advance,
    Filippe

    Filippe Soares Roza wrote:
    Hi to all.
    It's a pleasure to receive your help.
    In "FOR REC IN CURSOR(PARAMETERS) LOOP" command although the query return value does not enter the loop.
    Sounds simple, but I'm not seeing the flaw...
    Suggestions?
    Version: Oracle Database 10g Enterprise Edition Release 10.2.0.4.0
    Thank in advance,
    Filippe
    see a picture of my car that does not work.
    Tell me how to make my car go.
    How do I ask a question on the forums?
    SQL and PL/SQL FAQ

  • A strange error about cursor and dblink

    My dbms:Oracle8i Enterprise Edition Release 8.1.7.4.0
    I have a stored procedure, which inserts records from a remote database into a local table.
    The 'insert' statement have similar pattern:
    insert into table_a
    select table_b.columns from table_b@dblink
    where table_a.column in (select table_b.column from table_b@dblink);
    commit;
    There are about 100 'insert' statement in my procedure. But there is same error messages at the same
    place when the procedure is run. The error messages:ora-01000:maximum open cursors exceeded,ora-02063:
    preceding line from dblink. I have manually run the 'insert'statements before the error place and after the error place.
    The before and after statements are both OK.
    From google.com, I have learned that 'commit' will clear the implicit cursors from 'insert' statement. So I think
    the problem is ora-02063. Again, keywords 'ora-01000 ora-02063'from google.com, I found 'alter session close
    database link dblink' might solve the problem. I have add the 'alter session' statement after each 'commit' in
    my procedure. Unfortunately, same error happened again at the same place.
    I am puzzled. Would you like to give some advice? Thanks a lot!

    Hello
    Well, the best place to lookup error messages is here....
    http://www.oracle.com/pls/db92/db92.homepage
    It's also where all the rest of the database documentation is. As for this error, too many open cursors, as it suggests, one session has too many open. From the statement you are using to select the data, it seems like you are forming the statements dynamically, is this the case? If so, you're using cursors, and so there's a good chance you aren't closing them.
    HTH

  • Cursor Fetch Loop to Move data from one table to another

    Hi Gurus,
    I need to write a cursor fetch loop PL/SQL procedure that moves all the data from the students table to student_history table. Can anyone tell me how to do this please?
    Thanks

    and the instructions were specific:"Write a PL/SQL procedure that moves all the data from the students table to student_history table. You should use CURSOR FETCH LOOP to retrieve the data"
    Who in the world have given you that instruction? This person[s] should take their ABC learning too. I might have come up with 1001 ineffective and owful ways to perform some task, but to teach others to do it in the same way would be a bit arrogant. To copy the content of a table into another one in CURSOR FETCH LOOP is one of the worst solutions I've heard of. See
    http://asktom.oracle.com/pls/ask/f?p=4950:8:16840616406862738180::NO::F4950_P8_DISPLAYID,F4950_P8_CRITERIA:5008574230335

Maybe you are looking for

  • Colour Calibration / White Point setting - Is Imac Display really professional quality

    I am trying to calibrate my imac 27" using i1 Display2 calibration software. I am trying to set a traget of 6500 using the software but it advises the current is only 5600 and suggests moving the RGB sliders to get this current white point up to my 6

  • SAP E COMMERCE FOR ERP : Maintaining catalog variants in multiple languages

    Hi All, I have created a product catalog with 2 variants, one for english and other for russian, have maintained the texts in corresponding langiages in the layout area. I created a webshop and used the catalog variant for russian, but still when the

  • ITunes locked? Help!

    Hey all, When I tried to update to iTunes 10.1 today my iTunes wouldn't close and said 'The iTunes Library file is locked, on a locked disk, or you do not have write permission for this file'. I've tried dragging my iTunes Library to my desktop - iTu

  • How to install user 'hwd' from CD (SOLVED)

    Forgive me, but I've searched on how to install a user program. Namely I want to install 'hwh' I have remade the Don't Panic CD with 'hwd-4.8.2.bin.tar.gz' inside the arch/pkg directory on the cd. pacman see's it, but won't install it. I know using t

  • Where can I find the files I've downloaded off websites in my ipad?

    I've downloaded several PDF files and ePub files off of a website and when they are finished downloading they disappear and I can find them anywhere. I have iBooks and some of the times I can send the files to the iBooks but lately the option doesn't