Oracle FAQ Your Portal to the Oracle Knowledge Grid
HOME | ASK QUESTION | ADD INFO | SEARCH | E-MAIL US
 

Home -> Community -> Mailing Lists -> Oracle-L -> Re: pl/sql open cursor question

Re: pl/sql open cursor question

From: Jared Still <jkstill_at_cybcon.com>
Date: Sun, 28 Dec 2003 17:44:25 -0800
Message-ID: <F001.005DB2B9.20031228174425@fatcity.com>


Carel,

It might seem that the loop construct would be more expensive, but it didn't appear that way on my test system. ( 9.2.0.4, RH 8.0 )

function a:

create or replace function a return varchar2 is
begin

   for srec in (select dummy from ctest)    loop

      return srec.dummy;
   end loop;
   return null;
end;
/

function b:

create or replace function b return varchar2 is

   cursor c1
   is
   select dummy
   from ctest;

   v_dummy varchar2(1) := null;

begin

   open c1;
   fetch c1 into v_dummy;
   close c1;
   return v_dummy;
end;
/

The resource consumption for a 1000 iterations of each: ( a is the first column )

17:38:42 poirot.jks.com - jkstill_at_ts01 SQL> @run_stats

NAME                                           RUN1       RUN2       DIFF
---------------------------------------- ---------- ---------- ----------
LATCH.Consistent RBA                              0          1          1
LATCH.cache buffers lru chain                     1          0         -1
LATCH.lgwr LWN SCN                                0          1          1
LATCH.mostly latch-free SCN                       0          1          1
LATCH.session idle bit                            0          1          1
STAT...calls to get snapshot scn: kcmgss       3012       3013          1
STAT...calls to kcmgcs                            7          6         -1
STAT...cleanout - number of ktugct calls          0          1          1
STAT...consistent gets - examination              0          1          1
STAT...session cursor cache hits                  1          2          1
STAT...parse count (total)                        1          2          1
STAT...opened cursors current                     1          2          1
STAT...opened cursors cumulative                  1          2          1
STAT...messages sent                              0          1          1
STAT...free buffer requested                      1          0         -1
STAT...execute count                           1003       1004          1
STAT...deferred (CURRENT) block cleanout          4          3         -1
 applications
STAT...calls to kcmgas                            0          1          1
STAT...user commits                               0          1          1
STAT...active txn count during cleanout           0          1          1
LATCH.enqueues                                    0          1          1
LATCH.dml lock allocation                         0          2          2
LATCH.session allocation                          0          2          2
STAT...db block changes                          25         27          2
STAT...enqueue releases                           0          2          2
STAT...consistent gets                         3010       3012          2
LATCH.cache buffers chains                     6130       6133          3
STAT...redo entries                              17         20          3
STAT...recursive cpu usage                        4          7          3
STAT...db block gets                             30         33          3
LATCH.redo writing                                0          3          3
LATCH.undo global data                            1          4          3
LATCH.library cache                               7          4         -3
LATCH.enqueue hash chains                         0          4          4
LATCH.redo allocation                            18         22          4
LATCH.library cache pin                           7          3         -4
LATCH.messages                                    0          5          5
STAT...session logical reads                   3040       3045          5
STAT...commit cleanouts                           0          7          7
STAT...commit cleanouts successfully com          0          7          7
pleted
STAT...redo size                              27184      27820        636
STAT...recursive calls                         2004       3007       1003

42 rows selected.

The for loop actually appears to be somewhat less expensive in terms of database resources.

Jared

On Sun, 2003-12-28 at 11:39, Carel-Jan Engel wrote:
> What I don't understand is the loop construction:
>
> Actually only one (row) is read form the cursor, and then the function is
> left with a return. Because it's an unconditional return, the code within
> the loop will either execute once, or never. When no data is found NULL is
> returned. When an error occurs NULL is returned as well. So, why a loop?
>
> Wouldn't it be better to have something like:
>
> create or replace function XYZ(gid in number) return varchar2 is
> l_c1 tab1.C1%TYPE; /* local variable to store C1 */
> begin
> select c1
> into l_c1
> from tab1
> where id = gid;
>
> return l_c1;
>
> exception
> when no_data_found
> then return <some_error_code>; /* let the caller know that no data is
> found */
> when others
> then return 'ERROR: '||TO_CHAR(SQLCODE); /* return the error-code,
> preceded by the text ERROR for identification */
> end;
>
> Sure, a loop prevents an ORA-1422, but I don't think a loop construction
> should be abused for this. Just think about all loop controlling code that
> needs to be set up by the interpreter. tab1.ID should be unique, so a 1422
> normally cannot occur. Robust programming however asks us to prevent any
> error. I would prefer to think about how a 1422 should be handled, and
> write some code accordingly.
>
> Regards, Carel-Jan
>
> ===
> If you think education is expensive, try ignorance. (Derek Bok)
> ===
>
>
> At 09:39 28-12-03 -0800, you wrote:
> >Hi
> >
> >if we assume it is implements this way (see below) there will only be
> >one cursor since c_gid
> >is a bind variable and there for the cursor will be sharded from call to
> >call of the function.
> >
> >create or replace function XYZ (gid in number) return varchar2 is
> > cursor cur1(c_gid number) is select C1 from tab1 where id = c_gid;
> >begin
> > for x in cur1(gid) loop
> > return x.c1;
> > end loop;
> > return null;
> >exception
> > when others then return null;
> >end;
> >
> >It will only be one coursor
> >
> >Guang Mei wrote:
> >>
> >>I have a function like below (psudo code). If cursor cur1 have multiple
> >>rows, would the code leave the cursor open when this function is called?
> >>So if this function is called 1000 times, I would have 1000 open cursors?
> >>
> >>function XYZ(gid in number) return varchar2 is
> >> cursor cur1 is select C1 from tab1 where ID = gid;
> >>begin
> >> for x in cur1 loop
> >> return x.c1;
> >> end loop;
> >> return null;
> >>exception
> >> when others then return null;
> >>end;
> >>
> >>
> >
> >--
> >
> >Best regards/Venlig hilsen
> >
> ><mailto:peter.gram_at_miracleas.dk>Peter Gram
> >
> ><http://www.miracleas.dk/>Miracle<http://www.miracleas.dk/> A/S
> >Kratvej 2
> >DK - 2760 Måløv
> >Cell: (+45) 2527 7107
> >Phone: (+45) 4466 8855
> >Fax: (+45) 4466 8856
> >Home: (+45) 3874 5696
> >Email: <mailto:peter.gram_at_miracleas.dk>peter.gram_at_miracleas.dk

-- 
Please see the official ORACLE-L FAQ: http://www.orafaq.net
-- 
Author: Jared Still
  INET: jkstill_at_cybcon.com

Fat City Network Services    -- 858-538-5051 http://www.fatcity.com
San Diego, California        -- Mailing list and web hosting services
---------------------------------------------------------------------
To REMOVE yourself from this mailing list, send an E-Mail message
to: ListGuru_at_fatcity.com (note EXACT spelling of 'ListGuru') and in
the message BODY, include a line containing: UNSUB ORACLE-L
(or the name of mailing list you want to be removed from).  You may
also send the HELP command for other information (like subscribing).
Received on Sun Dec 28 2003 - 19:44:25 CST

Original text of this message

HOME | ASK QUESTION | ADD INFO | SEARCH | E-MAIL US