Oracle FAQ | Your Portal to the Oracle Knowledge Grid |
Home -> Community -> Mailing Lists -> Oracle-L -> Re: pl/sql open cursor question
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 -1applications
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 7pleted
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