Home » SQL & PL/SQL » SQL & PL/SQL » Unable to pass 1st value into the query (Oracle, 11.2.0.4.0, Windows 7 Professional 64 bit)
Unable to pass 1st value into the query [message #647113] Tue, 19 January 2016 23:01 Go to next message
buggleboy007
Messages: 282
Registered: November 2010
Location: Canada
Senior Member
My problem is as follows:

I am trying to fetch values from one table using BULK COLLECT. This brings a few values and based on the count , let's say if it brings 5 values, then I want all the five values to be passed into the cursor. However it's failing to pass all the five values and sends only the last value (i.e. collection.COUNT) and this is causing data to be missed for other values:

Code is as follows:

SET ECHO ON
SET SERVEROUTPUT ON 

DECLARE 

    lv_NumIRFareacd             IRF_MSG_TRNSCN_PRCS.irf_area_cd%TYPE;
    TYPE Typirfareacd_aa        IS TABLE OF IRF_MSG_TRNSCN_PRCS.irf_area_cd%TYPE INDEX BY PLS_INTEGER;
    lv_Varirfareacd_aa          Typirfareacd_aa;  
    lv_NumCountIRFareacd        PLS_INTEGER;  
    
    TYPE TypIrfareacdetails_aa IS RECORD
    (msgid                IRF_MSG.msg_id%TYPE,
     typecd               IRF_MSG.type_cd%TYPE,
     dscrpttxt            IRF_MSG.dscrpt_txt%TYPE,
     irf_areacd           IRF_MSG_TRNSCN_PRCS.irf_area_cd%TYPE,
     trnscnprcsid         IRF_MSG_TRNSCN_PRCS.trnscn_prcs_id%TYPE,
     recordcreatetms      IRF_MSG_TRNSCN_PRCS.record_create_tms%TYPE);
     
     TYPE lv_TypIrfareacodetails_aa IS TABLE OF TypIrfareacdetails_aa INDEX BY PLS_INTEGER;  
     lv_TypIrfareacdetails   lv_TypIrfareacodetails_aa;
     
      CURSOR cur_irfareacdmstrrecs IS
      SELECT A.msg_id,
              A.type_cd,
              A.dscrpt_txt,
              B.irf_area_cd,
              B.trnscn_prcs_id,
              B.record_create_tms
       BULK COLLECT INTO lv_TypIrfareacdetails
       FROM IRF_MSG A, IRF_MSG_TRNSCN_PRCS B
       WHERE (B.irf_area_cd =UPPER(lv_Varirfareacd_aa(lv_NumCountIRFareacd)))
       AND   (B.msg_id = A.msg_id);    
    
BEGIN
                  SELECT DISTINCT irf_area_cd 
                  BULK COLLECT INTO lv_Varirfareacd_aa
                  FROM irf_msg_trnscn_prcs
                  WHERE irf_area_cd IN ('STCC1', 'STCC2','STCC3','STCC4','STCC5');
                  
                  lv_NumCountIRFareacd:= lv_Varirfareacd_aa.COUNT;
                  DBMS_OUTPUT.Put_line('There are:'|| '  '||lv_NumCountIRFareacd||':'||'records or codes');
               

     
     --  FOR i in 1..lv_NumCountIRFareacd
           FOR i IN lv_Varirfareacd_aa.FIRST.. lv_Varirfareacd_aa.LAST
            LOOP
             
                   DBMS_OUTPUT.put_line('====================================');
                   DBMS_OUTPUT.ENABLE (buffer_size => NULL);
                   DBMS_OUTPUT.Put_line('DETAILS FOR:'||'    '||lv_Varirfareacd_aa(i));
                   
                   DBMS_OUTPUT.put_line('+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++');
                   DBMS_OUTPUT.put_line('RECORD # '||'       '||'MESSAGE ID'||'             '||'TYPE'||'            '||'                    DESCRIPTION'||'             '||'                                         AREA'||'            '||'                TRANSACTION #'||'             '||'                 DATE');      
                   DBMS_OUTPUT.put_line('++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++');                                                        
          END LOOP;
            
          OPEN cur_irfareacdmstrrecs;
              LOOP
               FETCH cur_irfareacdmstrrecs BULK COLLECT INTO lv_TypIrfareacdetails LIMIT 100;
               EXIT WHEN lv_TypIrfareacdetails.COUNT =0;
                 FOR j IN 1..lv_TypIrfareacdetails.COUNT
                 LOOP
                    DBMS_OUTPUT.put_line(j||'         '||        TO_CHAR(lv_TypIrfareacdetails(j).msgid)||'                   '||TO_CHAR(lv_TypIrfareacdetails(j).typecd)||'                           '||
                                            TO_CHAR(lv_TypIrfareacdetails(j).dscrpttxt)||'                                       '||TO_CHAR(lv_TypIrfareacdetails(j).irf_areacd)||'           '||
                                            TO_CHAR(lv_TypIrfareacdetails(j).trnscnprcsid)||'                    '||TO_CHAR(lv_TypIrfareacdetails(j).recordcreatetms, 'MM/DD/RRRR HH24:MI:SS'));
                 END LOOP; 
              
              END LOOP;
          CLOSE  cur_irfareacdmstrrecs;
END;            



Output of this is as follows:

There are:  2:records or codes
====================================
DETAILS FOR:    STCC1
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
RECORD #        MESSAGE ID             TYPE                                DESCRIPTION                                                      AREA                            TRANSACTION #                              DATE
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
====================================
DETAILS FOR:    STCC2
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
RECORD #        MESSAGE ID             TYPE               DESCRIPTION                                     AREA                            TRANSACTION #                              DATE
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1         82                   E                            invalid.                                       STCC2           45688912                    05/21/2015 22:08:46
2         82                   E                             invalid.                                       STCC2           45603640                    05/21/2015 13:53:15
3         82                   E                             invalid.                                       STCC2           45564718                    04/28/2015 13:17:53
4         82                   E                           invalid.                                       STCC2           45441667                    04/27/2015 18:39:48
5         82                   E                            invalid.                                       STCC2           45646276                    05/21/2015 19:45:59
6         82                   E                             invalid.                                       STCC2           45495568                    04/27/2015 18:40:40
7         82                   E                            invalid.                                       STCC2           45387611                    03/27/2015 17:34:53
8         82                   E                             invalid.                                       STCC2           45226637                    02/20/2015 15:02:39
9         82                   E                            invalid.                                       STCC2           45062947                    11/25/2014 16:22:03




The problem lies here:

      CURSOR cur_irfareacdmstrrecs IS
      SELECT A.msg_id,
              A.type_cd,
              A.dscrpt_txt,
              B.irf_area_cd,
              B.trnscn_prcs_id,
              B.record_create_tms
       BULK COLLECT INTO lv_TypIrfareacdetails
       FROM IRF_MSG A, IRF_MSG_TRNSCN_PRCS B
       WHERE (B.irf_area_cd =UPPER(lv_Varirfareacd_aa(lv_NumCountIRFareacd)))
       AND   (B.msg_id = A.msg_id);    

because lv_NumCountIRFareacd returns 2 (
lv_NumCountIRFareacd:= lv_Varirfareacd_aa.COUNT;
)

My question is how can I pass both the values in the above cursor. i.e. at the moment its only fetching values for STCC2 and ignoring STCC1. There are a couple of records for STCC1 and I am unable to pass the 1st value to the above cursor.

Can any one help?
Re: Unable to pass 1st value into the query [message #647118 is a reply to message #647113] Wed, 20 January 2016 00:35 Go to previous messageGo to next message
buggleboy007
Messages: 282
Registered: November 2010
Location: Canada
Senior Member
My question is how can I pass both the values in the above cursor. i.e. at the moment its only fetching values for STCC2 and ignoring STCC1. There are a couple of records for STCC1 and I am unable to pass the 1st value to the above cursor.

Can any one help?
Re: Unable to pass 1st value into the query [message #647122 is a reply to message #647118] Wed, 20 January 2016 02:05 Go to previous messageGo to next message
JNagtzaam
Messages: 36
Registered: July 2015
Location: Alkmaar
Member

This is very basic stuff: https://docs.oracle.com/cd/B19306_01/appdev.102/b14261/cursor_declaration.htm.
And you need to ask yourself if you really need 2 cursors/loops?
Re: Unable to pass 1st value into the query [message #647126 is a reply to message #647122] Wed, 20 January 2016 03:14 Go to previous messageGo to next message
cookiemonster
Messages: 13920
Registered: September 2008
Location: Rainy Manchester
Senior Member
You have specifically told it to only use a single value out of the array.
You need an in-list: varying in list

Or just combine the two into a single select.
And if you're limiting the bulk collect to 100 at a time you might as well just use a FOR LOOP as that bulk collects 100 records in the background anyway.
Re: Unable to pass 1st value into the query [message #647127 is a reply to message #647113] Wed, 20 January 2016 03:19 Go to previous messageGo to next message
flyboy
Messages: 1903
Registered: November 2006
Senior Member
https://community.oracle.com/thread/3888715
Quote:
You have a bigger problem. The code and approach are junk. Wrong. Flawed. Garbage.

You do realize that firstly (in the first loop) you are putting the headers to the DBMS_OUTPUT buffer and then you are putting there data of the last collection member (the one at LV_NUMCOUNTIRFAREACD).
Maybe you should use IN operator instead of the euality one (=) and a TABLE collection expression on a SQL type, something like
select * from dual where 'STCC1' in
( select column_value from table (sys.odcivarchar2list( 'STCC1', 'STCC2','STCC3','STCC4','STCC5' )) );

Or, better, use a single cursor as suggested in the other forum.

[Edit: Changed the query to use IN operator]

[Updated on: Wed, 20 January 2016 03:21]

Report message to a moderator

Re: Unable to pass 1st value into the query [message #647139 is a reply to message #647127] Wed, 20 January 2016 05:05 Go to previous messageGo to next message
JNagtzaam
Messages: 36
Registered: July 2015
Location: Alkmaar
Member

This will probably do the trick. Couldn't test it ofcourse Wink

DECLARE

  lv_numirfareacd irf_msg_trnscn_prcs.irf_area_cd%TYPE;

  TYPE typirfareacdetails_aa IS RECORD(
     msgid           irf_msg.msg_id%TYPE
    ,typecd          irf_msg.type_cd%TYPE
    ,dscrpttxt       irf_msg.dscrpt_txt%TYPE
    ,irf_areacd      irf_msg_trnscn_prcs.irf_area_cd%TYPE
    ,trnscnprcsid    irf_msg_trnscn_prcs.trnscn_prcs_id%TYPE
    ,recordcreatetms irf_msg_trnscn_prcs.record_create_tms%TYPE);

  TYPE lv_typirfareacodetails_aa IS TABLE OF typirfareacdetails_aa INDEX BY PLS_INTEGER;
  lv_typirfareacdetails lv_typirfareacodetails_aa;

  CURSOR cur_irfareacdmstrrecs IS
    SELECT a.msg_id
          ,a.type_cd
          ,a.dscrpt_txt
          ,b.irf_area_cd
          ,b.trnscn_prcs_id
          ,b.record_create_tms
      BULK COLLECT
      INTO lv_typirfareacdetails
      FROM irf_msg             a
          ,irf_msg_trnscn_prcs b
     WHERE (b.irf_area_cd = IN ('STCC1'
                               ,'STCC2'
                               ,'STCC3'
                               ,'STCC4'
                               ,'STCC5'))
           AND (b.msg_id = a.msg_id);

BEGIN

  OPEN cur_irfareacdmstrrecs;
  LOOP
    FETCH cur_irfareacdmstrrecs BULK COLLECT
      INTO lv_typirfareacdetails LIMIT 100;
    EXIT WHEN lv_typirfareacdetails.count = 0;

    FOR j IN 1 .. lv_typirfareacdetails.count
    LOOP
      IF j.irf_area_cd <> lv_numirfareacd
      THEN
        lv_numirfareacd := j.irf_area_cd;
        dbms_output.put_line('====================================');
        dbms_output.enable(buffer_size => NULL);
        dbms_output.put_line('DETAILS FOR:' || '    ' || lv_numirfareacd);
      
        dbms_output.put_line('+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++');
        dbms_output.put_line('RECORD # ' || '       ' || 'MESSAGE ID' || '             ' || 'TYPE' || '            ' || '                    DESCRIPTION' ||
                             '             ' || '                                         AREA' || '            ' || '                TRANSACTION #' ||
                             '             ' || '                 DATE');
        dbms_output.put_line('++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++');
      END IF;
      dbms_output.put_line(j || '         ' || to_char(lv_typirfareacdetails(j).msgid) || '                   ' || to_char(lv_typirfareacdetails(j).typecd) ||
                           '                           ' || to_char(lv_typirfareacdetails(j).dscrpttxt) || '                                       ' ||
                           to_char(lv_typirfareacdetails(j).irf_areacd) || '           ' || to_char(lv_typirfareacdetails(j).trnscnprcsid) ||
                           '                    ' || to_char(lv_typirfareacdetails(j).recordcreatetms
                                                            ,'MM/DD/RRRR HH24:MI:SS'));
    END LOOP;
  
  END LOOP;
  CLOSE cur_irfareacdmstrrecs;
END;
/
Re: Unable to pass 1st value into the query [message #647142 is a reply to message #647139] Wed, 20 January 2016 08:14 Go to previous messageGo to next message
cookiemonster
Messages: 13920
Registered: September 2008
Location: Rainy Manchester
Senior Member
Simpler version:
DECLARE

  l_prev_irf_area_cd irf_msg_trnscn_prcs.irf_area_cd%TYPE;
  
BEGIN

  FOR rec IN (SELECT a.msg_id
                  ,a.type_cd
                  ,a.dscrpt_txt
                  ,b.irf_area_cd
                  ,b.trnscn_prcs_id
                  ,b.record_create_tms
              FROM irf_msg a
              JOIN irf_msg_trnscn_prcs b ON b.msg_id = a.msg_id
              WHERE b.irf_area_cd = IN ('STCC1'
                                       ,'STCC2'
                                       ,'STCC3'
                                       ,'STCC4'
                                       ,'STCC5')) LOOP

    IF rec.irf_area_cd <> l_prev_irf_area_cd OR l_prev_irf_area_cd IS NULL THEN
      l_prev_irf_area_cd := rec.irf_area_cd;
      dbms_output.put_line('====================================');
      dbms_output.enable(buffer_size => NULL);
      dbms_output.put_line('DETAILS FOR:' || '    ' || rec.irf_area_cd);
      
      dbms_output.put_line('+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++');
      dbms_output.put_line('RECORD # ' || '       ' || 'MESSAGE ID' || '             ' || 'TYPE' || '            ' || '                    DESCRIPTION' ||
                           '             ' || '                                         AREA' || '            ' || '                TRANSACTION #' ||
                           '             ' || '                 DATE');
      dbms_output.put_line('++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++');
    END IF;
    
    dbms_output.put_line(j || '         ' || to_char(rec.msgid) || '                   ' || to_char(rec.typecd) ||
                         '                           ' || to_char(rec.dscrpttxt) || '                                       ' ||
                         to_char(rec.irf_areacd) || '           ' || to_char(rec.trnscnprcsid) ||
                         '                    ' || to_char(rec.recordcreatetms
                                                          ,'MM/DD/RRRR HH24:MI:SS'));
  END LOOP;

END;
Re: Unable to pass 1st value into the query [message #647163 is a reply to message #647142] Wed, 20 January 2016 22:05 Go to previous messageGo to next message
buggleboy007
Messages: 282
Registered: November 2010
Location: Canada
Senior Member
Cookie monster: Thanks a ton for your reply. I learnt a valuable lesson not to use BULK COLLECT as it took away a lot of PGA (actually I had developed another script which worked for the task in question but took away PGA;so ended up pasting the flawed code on the top - a kind of poor rework).

In fact later on in the day I used an implicit cursor(like the way you have mentioned) and then based on the results obtained, passed each transaction number to obtain the results via an explicit parametric cursor. In the end I was able to accomplish what I wanted via a FOR SELECT implicit cursor and then calling another explicit cursor. The query took about 59-1.09 seconds to execute.

Once again many thanks for your time.
Re: Unable to pass 1st value into the query [message #647164 is a reply to message #647122] Wed, 20 January 2016 22:07 Go to previous message
buggleboy007
Messages: 282
Registered: November 2010
Location: Canada
Senior Member
JNagtzaam wrote on Wed, 20 January 2016 02:05
This is very basic stuff: https://docs.oracle.com/cd/B19306_01/appdev.102/b14261/cursor_declaration.htm.
And you need to ask yourself if you really need 2 cursors/loops?


Your basic stuff link does not even work or open. Please ensure that the links work by testing them before posting it on the forum. Anyway, I know where you were trying to refer me and I was able to accomplish my task successfully.
Previous Topic: How To Get JV/34 as JV/0034 or JV/034 as JV/0034 or JV/0034 as JV/0034 using regular expression
Next Topic: separate string by comma
Goto Forum:
  


Current Time: Wed Apr 24 00:10:52 CDT 2024