Skip to Main Content
  • Questions
  • text of my sql's since the start of my session

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, sj.

Asked: September 26, 2001 - 9:04 pm UTC

Last updated: March 25, 2013 - 2:34 pm UTC

Version: 8.6

Viewed 1000+ times

You Asked

Tom


I want to query all the sql's I wrote since the start of my session from v$sqlarea. I want to know how should I write this query and how should I format it so that I will have a well formatted list of query list,

and I also want the buffer hits, disk hits for this query from v$sqlarea.

which views should I join for the above purpose.

and what kind of details does mystats give, does it give details by query or by session.


How many queries will be in the v$sqlarea, i.e. what is the criteria for pushing a query out of v$sqlarea.

Thank you

and Tom said...

You cannot do that, that information is not tracked in the SGA. All of the queries you ran since you session began might not even be in the shared pool and we definitely don't remember which ones YOU executed and the buffer counts YOU encountered.

This is what SQL_TRACE, TIMED_STATISTICS and TKPROF are useful for:

</code> http://asktom.oracle.com/~tkyte/tkprof.html <code>


v$mystats is session level statistics.


As for how many queries are in the shared pool -- that is a direct function of the complexity of the query (size it takes to store it) and the size of your shared pool. Could be few queries, could be lots.

Queries get pushed out on an LRU basis when more space is needed for new queries.

Rating

  (23 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Clarify

A reader, September 27, 2001 - 10:38 am UTC

So where do the sql's found in v$sqlarea, come from.
How long do they stay in this view. What is the criteria for them to stay in the view.

IN
</code> http://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:497421739750,%7BSET%7D%20and%20%7BSERVEROUTPUT%7D%20and%20%7BON%7D <code>

You do state that the active sql can be captured.

So do you mean that only active sql which is currently executing in different sessions is only found in V$sqlarea.

Once again..

What is the actual criteria to put a query into v$sqlarea, and to kick it out of the v$sqlarea.

number of sql's in shared pool = no of sql's in v$sqlarea
is this statement true



Tom Kyte
September 27, 2001 - 2:37 pm UTC

The sql you see there is what is currently in the shared pool. All of the sql you executed since the beginning of your session MAY or MAY NOT be in there still. Even if it all IS -- the fact that YOU executed is NOT tracked.

There will be one copy of "select * from emp" typically in the shared pool. 1,000,000 sessions may each have executed it 5 times. We do not track who executed and what sort of buffer reads they have.

If you are currently executing a statement -- it will be in the shared pool. Hence we can get the ACTIVE sql -- but not sql you executed 5 minutes ago.

v$sql and related views are just peeking at the memory of the SGA. The criteria for being in there is someone parsed you. The criteria for getting out is that no one has used you for a while.

v$sqlarea is an aggregate view, v$sql is not. duplicates (child cursors) are removed in v$$sqlarea (you should use v$sql for casual queries for this reason -- more efficient)

It is not really true that count(*) in v$sqlarea is count of queries in the shared pool, its the count of the distinct query texts in the shared pool. That is

"select * FROM T"

might be in the shared pool two times because the user mike, who owns mike.t, submitted and the user tom, who owns tom.t, submitted it and its really TWO different queries with the same text.

A Reader

A Reader, September 28, 2001 - 12:54 am UTC

<quote>
v$sqlarea is an aggregate view, v$sql is not. duplicates (child cursors) are removed in v$$sqlarea (you should use v$sql for casual queries for this reason -- more efficient)
<quote>

Could you give an example of *duplicates (child cursors)"

Thanks

Tom Kyte
September 28, 2001 - 6:56 am UTC

Sure, I have two users OPS$TKYTE and SCOTT.  they both have EMP tables.  They both ran some queries.  When I look in v$sqlarea:

ops$tkyte@ORA817DEV.US.ORACLE.COM> select sql_text, version_count from v$sqlarea where sql_text like 'select * from emp%';

SQL_TEXT                                 VERSION_COUNT
---------------------------------------- -------------
select * from emp                                    1
select * from emp e1                                 2
select * from emp e2                                 2
select * from emp, dept where emp.deptno             1
 = dept.deptno

select * from emp@ora815.us.oracle.com               1


I see 2 versions of select * from emp e1, select * from emp e2. I only see the query once but I know there are two versions.  So, I goto v$sql:


ops$tkyte@ORA817DEV.US.ORACLE.COM> select sql_text, parsing_user_id, parsing_schema_id from v$sql where sql_text like 'select * from emp%';

SQL_TEXT                                 PARSING_USER_ID PARSING_SCHEMA_ID
---------------------------------------- --------------- -----------------
select * from emp                                      0                 0
select * from emp, dept where emp.deptno              28                28
 = dept.deptno

select * from emp e2                                  28                28
select * from emp e2                                   0                 0
select * from emp@ora815.us.oracle.com                28                28
select * from emp e1                                  28                28
select * from emp e1                                   0                 0

7 rows selected.

And I can see why.  The select * from emp e2 queries where parsed by different users, with different effective (parsing schema id) ids.  They are the same text -- totally different queries.

 

READER

Reader, September 28, 2001 - 12:55 pm UTC

Given "PARSING_USER_ID PARSING_SCHEMA_ID" be the same
and ivalidations = 0, what other causes are for multiple versions

Thanks

Tom Kyte
September 28, 2001 - 2:08 pm UTC

session level settings play into this hugely

o different optimizer goals
o different sort area sizes
o different optimizer_* parameters
o and so on.

each of those will cause a different plan to be generated (hence child cursors)



how to see actual bind variable values

P, March 25, 2003 - 6:11 pm UTC

hi tom,
is there a way to see actual values for bind variables instead of :1 :2 in v$sqlarea/v$sql views?


Tom Kyte
March 25, 2003 - 8:42 pm UTC

no, there is not. they are in the UGA of the session which is normally in the PGA memory only.

remember -- v$sql/sqlsarea represent SHARED stuff -- there could be thousands of :1 values for any single statement in there.

Excellent!

A Reader, March 25, 2003 - 9:48 pm UTC

My unserstanding is that each session in dedicated server architecture will have its own UGA/PGA and it is not part of SGA. My question related to your comment above "no, there is not. they are in the UGA of the session which is normally in the PGA memory only." If the values for bind variables are in UGA, why can't a current session see the value of bind variables that are used in that session. Is there a way to see it at all? Thanks.

Tom Kyte
March 26, 2003 - 7:23 am UTC

a current session can, v$sql_bind_data, v$sql_bind_metadata, session specific v$ views.

Truncated SQL_TEXT

Fred Shimaya, August 13, 2003 - 9:32 pm UTC

Tom,

I am interested in looking at very long statements in v$sql, but most of those are truncated. Thus I can't see if bind variables were being used. Is there a way to see the whole statement?

Fred

Tom Kyte
August 13, 2003 - 9:42 pm UTC

v$SQLTEXT_WITH_NEWLINES

thanks a mucho!

Fred Shimaya, August 13, 2003 - 9:54 pm UTC

Senor El Caro,

Gracias por la ayuda!



Auditing SQL

Praveen, August 14, 2003 - 12:17 am UTC

Hi Tom,

Version : Oracle 8.1.7

I am developing an audit trail for our warehouse system. I want to trap the sql statements if user deletes, updates or truncates the table. How to trap the sql's that user is executing. I tried using the following query but always got no rows found.

select distinct substr(sql_text,1,100) IN_TRIGGER into v_sql_text
from v$sql
where address in (select sql_address from v$session
where osuser = sys_context('userenv','os_user')
and status = 'ACTIVE'
)
and sql_text not like '%IN_TRIGGER%'

Tom Kyte
August 14, 2003 - 7:54 am UTC

you cannot get the text of the query in 8i.

you can in 9i using a trigger -- there is a function provided for doing so.

When was the last time shared pool object was flushed?

Sai, September 22, 2003 - 4:15 pm UTC

Hi Tom,

I would like to know "when was the last time shared pool flushed/aged out any object from the pool".

If I have a job set up to collect snapshot of v$sql every 30 mins, is it safe to assume that none of the sql statements were aged out or flushed out from the shared pool if the first_load_time is less than last 30 mins?

Thanks

Tom Kyte
September 22, 2003 - 8:09 pm UTC

not safe, the entire entry could "disappear" - the thing being flushed itself could "go away" entirely.

When was the last time shared pool object was flushed?

Sai, September 22, 2003 - 9:34 pm UTC

Hi Tom,

I request you to help me with this question. Why would Oracle flush any object out of shared pool if there are no new sql statements being executed, unless somebody flush out entire shared pool. With this assumption, I thought, Oracle didn't yet flushed any objects out since max(to_date(first_load_time,......')), in other words, the last time Oracle flushed any object could be <= max(to_date(first_load_time,'.....)). Please explain.

Thanks.

Tom Kyte
September 22, 2003 - 9:47 pm UTC

ops$tkyte@ORA920LAP> create table t ( x int );
Table created.

ops$tkyte@ORA920LAP> select * from t test;
no rows selected

ops$tkyte@ORA920LAP> select first_load_time from v$sql where sql_text = 'select * from t test';

FIRST_LOAD_TIME
-------------------
2003-09-22/21:42:38

ops$tkyte@ORA920LAP> alter table t add y int;
Table altered.

ops$tkyte@ORA920LAP> select * from t test;
no rows selected

ops$tkyte@ORA920LAP> select first_load_time from v$sql where sql_text = 'select * from t test';

FIRST_LOAD_TIME
-------------------
2003-09-22/21:42:38


Ok, so what does this show?  well, nothing directly but -- obviously, "select * from t test" was invalidated and then rebuilt -- but the load time didn't change (and I type fast, but not that fast)...

so, what if "select * from t test" took 5 times the amount of space?  something might have to go.

it could be that the statements are in v$sql -- but is invalidated -- so not really in the shared pool truly.  So, they actually get parsed and loaded up -- flushing other stuff out as well.  (statements do not fall out of v$sql when invalidated...) 

A reader, September 23, 2003 - 12:23 am UTC


Bind variables etc.

Neil, September 23, 2003 - 7:14 am UTC

The trace analyzer will give you the values of your bind variables. Only retrospectivly, though. Get TRCA.zip from technet...

For Neil

Riaz Shahid, September 23, 2003 - 11:08 am UTC

Neil !

Can you please paste here the link for trca.zip ?

Thanks

Tom Kyte
September 23, 2003 - 11:40 am UTC

it is actually on metalink.oracle.com, just search for trca.zip and it pops right up

View all the SQLs executed during the day

A reader, February 01, 2005 - 12:39 pm UTC

Hi Tom,
I need to see all the SQLs executed on a DataBase during a day. How can I achieve that?
Also, is that possible to get the parameters passed with the SQLs ? If yes then HOW ?

Could you provide the complete details or I can find it somewhere ?
Thanks

Tom Kyte
February 01, 2005 - 2:20 pm UTC

dbms_fga would be one way -- you can audit all selects. including the binds.

supplied packages guide

or search this site for dbms_fga.





review

Sven, April 07, 2005 - 10:38 am UTC

Hi Tom,

If I execute the following query:
select sql_text, hash_value, address, VERSION_COUNT, LOADED_VERSIONS,
OPEN_VERSIONS, EXECUTIONS, LOADS, INVALIDATIONS, PARSE_CALLS
from v$sqlarea
where 1=1
order by VERSION_COUNT desc
;

hash_value: 3241877694
address 00000003996B1AE0
VERSION_COUNT 1005
LOADED_VERSIONS 435
OPEN_VERSIONS 0
EXECUTIONS 435
LOADS 1005
INVALIDATIONS 0
PARSE_CALLS 435

I can see for one cursor to have 1005 "VERSION_COUNT". If I take the address of this cursor and execute:

select *
from v$sql_shared_cursor
where kglhdpar = '00000005E3FDE8E0'
and (unbound_cursor = 'Y' or
sql_type_mismatch = 'Y' or
optimizer_mismatch = 'Y' or
outline_mismatch = 'Y' or
stats_row_mismatch = 'Y' or
literal_mismatch = 'Y' or
sec_depth_mismatch = 'Y' or
explain_plan_cursor = 'Y' or
buffered_dml_mismatch = 'Y' or
pdml_env_mismatch = 'Y' or
inst_drtld_mismatch = 'Y' or
slave_qc_mismatch = 'Y' or
typecheck_mismatch = 'Y' or
auth_check_mismatch = 'Y' or
bind_mismatch = 'Y' or
describe_mismatch = 'Y' or
language_mismatch = 'Y' or
translation_mismatch = 'Y' or
row_level_sec_mismatch = 'Y' or
insuff_privs = 'Y' or
insuff_privs_rem = 'Y' or
remote_trans_mismatch = 'Y' or
logminer_session_mismatch = 'Y' or
incomp_ltrl_mismatch = 'Y' or
overlap_time_mismatch = 'Y' or
sql_redirect_mismatch = 'Y' or
mv_query_gen_mismatch = 'Y' or
user_bind_peek_mismatch = 'Y' or
typchk_dep_mismatch = 'Y' or
no_trigger_mismatch = 'Y' or
flashback_cursor = 'Y')
;

I get no result.
Any idea what could be the reason of so high version count?

Thanks.

Sven

Tom Kyte
April 07, 2005 - 11:37 am UTC

addresses appear different?

review

sven, April 07, 2005 - 12:29 pm UTC

No, the addresses are the same.
For this sql, I did a query on v$sql => address the same, child_address different, module SQL*Plus.
In v$sql_plan they all have separate sql plans (child_number is different) which are the same.
Any thoughts?

Tom Kyte
April 07, 2005 - 12:45 pm UTC

hash_value: 3241877694
address 00000003996B1AE0 <<<<<<<<<<<<=================
VERSION_COUNT 1005
LOADED_VERSIONS 435
OPEN_VERSIONS 0
EXECUTIONS 435
LOADS 1005
INVALIDATIONS 0
PARSE_CALLS 435

I can see for one cursor to have 1005 "VERSION_COUNT". If I take the address of
this cursor and execute:

select *
from v$sql_shared_cursor
where kglhdpar = '00000005E3FDE8E0' <<<<<<<<<<<<===============
and (unbound_cursor = 'Y' or


look different to me.

review

sven, April 07, 2005 - 1:53 pm UTC

No, sorry for the misunderstanding. I just copied/paste a query for some other object that I have look for.
My intention was to show you which query I have used to obtain the result.
Really, the addresses are the same, the execution plans are the same but as I said in v$sql_plan they all have separate sql plans (child_number is different) generated.
If you like I can post you a results or send you zip with the results.
Sorry once again.



querying v$sqlarea

Andrew, October 07, 2005 - 10:23 am UTC

Tom,
For this question, and many others you answer with queries to sys.v$ tables(views).
questions:
1. are v$ tables are memory tables?
2. are queries to v$tables read consistent?
3. If queries to v$tables are read consistent, what is the mechanism that provides the consistency?
4. is it bad to run queries that join v$ tables with non v$tables - queries that might take many seconds to complete?
5. Will long running v$queries takeup resources?



Tom Kyte
October 07, 2005 - 9:37 pm UTC

1) most are
2) they are documented as not being read consistent
3) see #2
4) v$ tables require in most cases latched access to data structures, that can be a problem (while latched - no modifications, while waiting to be latched - you waiting). queries should be "short" yes.
5) yes, see #4

first load and last load

A reader, February 10, 2006 - 11:23 am UTC

Hi

What is the difference between first_load_time and last_load_time in v$sql?

I have SQL statements which has first_load_time from 1 month ago and last_load_time from 2 days ago. I am puzzled what are they?



Tom Kyte
February 10, 2006 - 1:18 pm UTC

http://docs.oracle.com/docs/cd/B19306_01/server.102/b14237/dynviews_2113.htm#sthref4036

That has the defintion of each - now, now for the demo ;)

ops$tkyte@ORA10GR2> alter system flush shared_pool;
System altered.
 
ops$tkyte@ORA10GR2> create table t ( x int );
Table created.
 
ops$tkyte@ORA10GR2> alter session set optimizer_mode=all_rows;
Session altered.
 
ops$tkyte@ORA10GR2> select * from t;
no rows selected
 
ops$tkyte@ORA10GR2> exec dbms_lock.sleep(3);
PL/SQL procedure successfully completed.
 
ops$tkyte@ORA10GR2> alter session set optimizer_mode=first_rows;
Session altered.
 
ops$tkyte@ORA10GR2> select * from t;
no rows selected
 
ops$tkyte@ORA10GR2> select first_load_time, last_load_time from v$sql where sql_text = 'select * from t';
 
FIRST_LOAD_TIME     LAST_LOAD_TIME
------------------- -------------------
2006-02-10/18:00:02 2006-02-10/18:00:02
2006-02-10/18:00:02 2006-02-10/18:00:05

<b>first load time is the load time of the parent.  for the first query (which is also the "parent" of all queries that look like select * from t), we have a first_load_time = last_load_time, it was last "optimized" when it was first loaded.

For the second query, 3 seconds later with a different optimizer environment, we have a first_load_time that is consistent (we expect it to be) with the first - it is the parents load time - but the last_load_time, the last time IT was optimized is 3 seconds later.

Let's add an index, to invalidate the existing cursors and causing them to be hard parsed next time:</b>

 
ops$tkyte@ORA10GR2> create index t_idx on t(x);
Index created.
 
ops$tkyte@ORA10GR2> exec dbms_lock.sleep(3);
PL/SQL procedure successfully completed.
 
ops$tkyte@ORA10GR2> alter session set optimizer_mode=all_rows;
Session altered.
 
ops$tkyte@ORA10GR2> select * from t;
no rows selected
 
ops$tkyte@ORA10GR2> exec dbms_lock.sleep(3);
PL/SQL procedure successfully completed.
 
ops$tkyte@ORA10GR2> alter session set optimizer_mode=first_rows;
Session altered.
 
ops$tkyte@ORA10GR2> select * from t;
no rows selected
 
ops$tkyte@ORA10GR2> select first_load_time, last_load_time from v$sql where sql_text = 'select * from t';
 
FIRST_LOAD_TIME     LAST_LOAD_TIME
------------------- -------------------
2006-02-10/18:00:02 2006-02-10/18:00:08
2006-02-10/18:00:02 2006-02-10/18:00:11

<b>Now, note that the first_load_time stayed the same - as long as the statement doesn't entirely flush out of the shared pool - it will stay that way.

However, the create index we just did caused the last_load_time for the first query to change - we just re-optimized that plan.  Likewise for the second.

We can read that as:

the first time we think we saw 'select * from t' was 2006-02-10/18:00:02.  The last time we hard parsed (and hence optimized) the first child cursor was 2006-02-10/18:00:08.  The second child cursor was last optimized on 2006-02-10/18:00:11.

</b>
 

v$sql

Anoop Gupta, March 23, 2006 - 2:31 am UTC

Hi Tom,

I am executing a procedure that contains a set of delete and insert statements.

When I run this procedure in my development database and no other queries or procedure are running in same database. A query is execting unecessary very frequently although it is not that procedure.


The number of execution of that query I am able to view in V$sql.

The output of v$sql is as follows :-

SQL_TEXT SHARABLE_MEM PERSISTENT_MEM RUNTIME_MEM SORTS LOADED_VERSIONS OPEN_VERSIONS USERS_OPENING EXECUTIONS USERS_EXECUTING LOADS FIRST_LOAD_TIME INVALIDATIONS PARSE_CALLS DISK_READS BUFFER_GETS ROWS_PROCESSED COMMAND_TYPE OPTIMIZER_MODE OPTIMIZER_COST PARSING_USER_ID PARSING_SCHEMA_ID KEPT_VERSIONS ADDRESS TYPE_CHK_HEAP HASH_VALUE CHILD_NUMBER MODULE MODULE_HASH ACTION ACTION_HASH SERIALIZABLE_ABORTS OUTLINE_CATEGORY

select count(1) from "CPS"."CG016_DATA_IN" where "CSS_RESPS_SEQ" = :1 4995 520 1328 5 1 0 0 5 0 1 2006-03-23/06:10:44 0 1 2 25 5 3 CHOOSE 0 0 0 0 808BD240 00 3502453221 0 0 0 0



Could you please tell me what might be the reason due to this query is coming in v$sql although it is not there in code any where.

It seems query ( select count(1) from "CPS"."CG016_DATA_IN" where "CSS_RESPS_SEQ" = :1) is generating by oracle dynamically.


Waiting for your response....












Tom Kyte
March 23, 2006 - 10:42 am UTC

You have a foreign key.

You are deleting from the parent.

We are checking for any child records.



(make sure that foreign key is INDEXED! else a full scan for every parent row deleted)

v$sql

Anoop Gupta, March 24, 2006 - 6:43 am UTC

Tom Thanks for your prompt response....

This is really very useful for me always.....




Elapsed time

Sunil, August 21, 2007 - 6:24 am UTC

Hi Tom,

I'm bit perplexed by the elapsed time in my v$sql

UPDATE ods_router_tables SET last_data_received = :b1, last_data_received_dst = :b3 WHERE table_name = :b2 AND NVL(last_data_received,TO_DATE('01-JAN-1980','DD-MON-YYYY')) < :b1

Executions: 2786327
Disk reads: 0
Buffer gets: 6023381
Rows processed: 423713
Optimizer cost: 1
Sorts: 0
CPU Time: 898500000
Elapsed Time: 1.84467440681166E19

This table is quite small, only 44 records and if i run the statement in Sql plus, it runs in a flash. But why this enormous Elapsed time in V$SQL. Is my conversion of this time to seconds/execution correct?

Elapsed time in seconds/execution: 1.84467440681166E19/1000000/2786327=6620451 seconds!

I guess there is something seriously wrong here. I'm running on a 4 CPU server.

I see similar figures in some of the innocent looking Insert statements as well.

thanks in advance,
Sunil
Tom Kyte
August 22, 2007 - 11:29 am UTC

looks like a bad value.

it is obviously wrong - please utilize support. might be an overflow (typically seen in parallel query execution

Weird behaviour on 11g

A reader, March 14, 2013 - 4:29 pm UTC

Tom,
I have this scenario where I rewrote a query thats running on a RAC environment and it generated two different plans for two
different sets of inputs.
I am using binds.
Now, I did an alter system flush shared_pool and the entries dissapeared from gv$sqlarea.

the weird thing is, when I check after some time, they reappear with the same plan_hash_value and same (ie old) first_load_time.
How is that possible?

thanks,

Tom Kyte
March 25, 2013 - 2:34 pm UTC

well, the plans are to be expected. Sounds like adaptive cursor sharing - where a plan will be developed based on the bind inputs and multiple plans are definitely permitted. So, that isn't a surprise.

flushing the shared pool will remove what it can - but that doesn't mean everything goes. If bits of that cursor are had to stick around (perhaps that query was open somewhere) - then it will. the plans might get flushed (we can recreate those easily).

remember plsql does things like caching of cursors.

consider - single user (just me, i know no one else is running this sql) and I reset my session (force all cursors to truly close)

ops$tkyte%ORA11GR2> connect /
Connected.
ops$tkyte%ORA11GR2> alter system flush shared_pool;

System altered.

ops$tkyte%ORA11GR2> declare
  2          cursor c is select * from scott.emp where 1=0;
  3  begin
  4          open c;
  5          close c;
  6  end;
  7  /

PL/SQL procedure successfully completed.

ops$tkyte%ORA11GR2> select sql_text, first_load_time from v$sql where sql_text = 'SELECT * FROM SCOTT.EMP WHERE 1=0';

SQL_TEXT
-------------------------------------------------------------------------------
FIRST_LOAD_TIME
-------------------
SELECT * FROM SCOTT.EMP WHERE 1=0
2013-03-25/10:33:11


ops$tkyte%ORA11GR2> connect /
Connected.
ops$tkyte%ORA11GR2> alter system flush shared_pool;

System altered.

ops$tkyte%ORA11GR2> exec dbms_lock.sleep(5);

PL/SQL procedure successfully completed.

ops$tkyte%ORA11GR2> declare
  2          cursor c is select * from scott.emp where 1=0;
  3  begin
  4          open c;
  5          close c;
  6  end;
  7  /

PL/SQL procedure successfully completed.

ops$tkyte%ORA11GR2> select sql_text, first_load_time from v$sql where sql_text = 'SELECT * FROM SCOTT.EMP WHERE 1=0';

SQL_TEXT
-------------------------------------------------------------------------------
FIRST_LOAD_TIME
-------------------
SELECT * FROM SCOTT.EMP WHERE 1=0
2013-03-25/10:33:15




new first load time... however:


ops$tkyte%ORA11GR2> connect /
Connected.
ops$tkyte%ORA11GR2> alter system flush shared_pool;

System altered.

ops$tkyte%ORA11GR2> declare
  2          cursor c is select * from scott.emp where 1=0;
  3  begin
  4          open c;
  5          close c;
  6  end;
  7  /

PL/SQL procedure successfully completed.

ops$tkyte%ORA11GR2> select sql_text, first_load_time from v$sql where sql_text = 'SELECT * FROM SCOTT.EMP WHERE 1=0';

SQL_TEXT
-------------------------------------------------------------------------------
FIRST_LOAD_TIME
-------------------
SELECT * FROM SCOTT.EMP WHERE 1=0
2013-03-25/10:34:17


ops$tkyte%ORA11GR2> REM  connect /
ops$tkyte%ORA11GR2> alter system flush shared_pool;

System altered.

ops$tkyte%ORA11GR2> exec dbms_lock.sleep(5);

PL/SQL procedure successfully completed.

ops$tkyte%ORA11GR2> declare
  2          cursor c is select * from scott.emp where 1=0;
  3  begin
  4          open c;
  5          close c;
  6  end;
  7  /

PL/SQL procedure successfully completed.

ops$tkyte%ORA11GR2> select sql_text, first_load_time from v$sql where sql_text = 'SELECT * FROM SCOTT.EMP WHERE 1=0';

SQL_TEXT
-------------------------------------------------------------------------------
FIRST_LOAD_TIME
-------------------
SELECT * FROM SCOTT.EMP WHERE 1=0
2013-03-25/10:34:17





comment out that reconnect - and the cursor "stays", it could not be flushed right then.