Excellent - clear and educational on multiple fronts
Brian White, September 24, 2001 - 10:48 am UTC
 
 
As with many questions on this forum, the answer highlights techniques that will prove generally useful and is explained in a way that provides true education.  I've learned so much by reading Tom's new book in conjunction with reviewing the questions answered in this forum. 
 
 
Very very Good Example!
Olga, December  16, 2003 - 7:58 am UTC
 
 
Yes, Tom is great! 
Reading Tom's Books and his web-site is better than any ocp course, i bet! That's Oracle live and no pseudo science. I spent so much money for Oracle books where the pages were full of nothing (like a HTML-Reference in a JAVA-Book), now I chucked them away.
Many Thanks Tom! 
 
 
CLOB
Ik, January   19, 2004 - 5:08 am UTC
 
 
Tom,
Hope you are back from your trip?
Two questions 
(1) I have almost the same situation except that my function gets called within an SQL statement. I am using a CLOB datatype inorder to return a string > 4000. 
I have followed your same methodology and iam opening the CLOB in a separate PL/SQL block within the package.
But, my nocache_lobs count shows 20 (which is equal to the number of rows returned by the SQL). 
How do i bring the count down to 1?
(2) This question is triggered from your usage of the anonymous PL/SQL block.
I have a PL/SQL Table declared at the package level. As per design, this table builds up as the SQL progresses through the rows and should hold data for the duration of the SQL.
I have a separate procedure in the same package which i call (before executing the SQL again)  inorder to flush the PL/SQL table.
For eg:- 
SELECT package.function(arg1,arg2...argn) from table1..n
Before i execute the same SQL again in the same session i have to call the procedure to flush the table.
Tom, is there any way to tell whether the package is called second time from a different (or same) query in the same session. If so, i need to clear it.
Thank You
 
 
January   19, 2004 - 9:34 am UTC 
 
1) the caller must close the lob.
2) not following you.  since you cannot select from a PLSQL table type?  one would need a small, yet complete, but concise example of what you mean. 
 
 
 
Further on the same posting
Ik, January   19, 2004 - 6:37 am UTC
 
 
Tom,
Further to question (1) on CLOBs - I found that by using an anonymous PL/SQL block to call the function results in creation of only one NOCACHE_LOB. Whereas, the same query when executed either in SQL Plus or through Oracle Reports (where it is actually used), the count= number of times the function was called.
Is there an overhead this way? How do i minimize this.
Also, there is a performance difference when i have an anonymous PL/SQL block within the package to do the CREATION and OPEN once for the CLOB (your way) vs...doing it eachtime inside the function. Contrary to what i expected the second option repeatedly came out faster.
BEGIN
        -- elaboration code, run once when package
       -- is first accessed in a session
        DBMS_LOB.CREATETEMPORARY(v_retvalue, FALSE);
        DBMS_LOB.OPEN(v_retvalue,dbms_lob.lob_readwrite);
vs
        v_retvalue       CLOB;
   BEGIN
        DBMS_LOB.CREATETEMPORARY(v_retvalue, FALSE, DBMS_LOB.CALL);
        DBMS_LOB.OPEN(v_retvalue,dbms_lob.lob_readwrite);
        DBMS_LOB.TRIM(v_retvalue,0);
Thanks. 
 
 
can I select into a clo?
RN, December  28, 2005 - 3:04 pm UTC
 
 
Tom, 
I did lot of searches in your site, but could not get it working. I want to populate the query plan returned by function dbms_xplan.display_awr to a CLOB field in a table.
Something like this, can I SELECT INTO A CLOB directly?
  1  declare
  2  v_sql_id varchar2(13) :='0h7jc6t42jsdy';
  3  v_plan clob;
  4  begin
  5  SELECT * into v_plan FROM TABLE(dbms_xplan.display_awr(v_sql_id));
  6  insert into test1 values(v_sql_id, v_plan);
  7  commit;
  8* end;
SQL> /
declare
*
ERROR at line 1:
ORA-01422: exact fetch returns more than requested number of rows
ORA-06512: at line 5 
Appreciate an example. Thank you verymuch. 
 
 
December  28, 2005 - 6:06 pm UTC 
 
well, that query returns "many rows" - each of which is a varchar2(300) 
ops$tkyte@ORA10GR2> create or replace view vw as SELECT *  FROM TABLE(dbms_xplan.display_awr(null));
View created.
ops$tkyte@ORA10GR2> desc vw;
 Name                                     Null?    Type
 ---------------------------------------- -------- ----------------------------
 PLAN_TABLE_OUTPUT                                 VARCHAR2(300)
you would have to (psuedo code here)
   insert into test1 values (v_sql_id, empty_clob() ) 
      returning plan into v_plan;
   for x in ( select * from table ( .... ) )
   loop
       dbms_lob.writeAppend( v_plan, length(x.plan_table_output), 
                             x.plan_table_output );
   end loop;
 
 
 
 
 
Excellent peice of info
Andrew, February  15, 2006 - 7:23 pm UTC
 
 
We came across the exact same scenario.
That is what I suspected, that you would have to free all clobs yourself, but I also like the package variable solution.
 
 
 
dbms_xplan.display_awr
Roland, August    16, 2007 - 7:46 pm UTC
 
 
Hi Tom,
Regarding dbms_xplan.display_awr.  We have an update statement identified by the following sql_id - dr7mvk6j9jnfj and uses the following Plan Hash Value -  3167053118.  The unfortunate  part is that the plan in question does not reflect an accurate row count that exist in the table.  Stats are gathered nightly witht the automatic job in 10g, but the plan that the sql uses still reflects the wrong row count.
select * from table(dbms_xplan.display_awr('dr7mvk6j9jnfj'))
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------
SQL_ID dr7mvk6j9jnfj
--------------------
UPDATE "DEP"."APPLICATION_DATA" SET "SYS_UPDATEDATE" = SYS_EXTRACT_UTC(CURRENT_TIMESTAMP),
"SYS_SESSIONID" = 0, "SYS_STATE" = MYBITAND("SYS_STATE", 18446744073709551613)  WHERE
"SYS_SESSIONID" = :V1
Plan hash value: 3167053118
---------------------------------------------------------------------------------------------------------
| Id  | Operation            | Name             | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
---------------------------------------------------------------------------------------------------------
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------
|   0 | UPDATE STATEMENT     |                  |       |       |    19 (100)|          |       |       |
|   1 |  UPDATE              | APPLICATION_DATA |       |       |            |          |       |       |
|   2 |   PARTITION RANGE ALL|                  |  1093 | 18581 |    19   (0)| 00:00:01 |     1 |     3 |
|   3 |    TABLE ACCESS FULL | APPLICATION_DATA |  1093 | 18581 |    19   (0)| 00:00:01 |     1 |     3 |
---------------------------------------------------------------------------------------------------------
An autotrace shows the cost we are getting from the explain plan.
Execution Plan
----------------------------------------------------------
Plan hash value: 3167053118
--------------------------------------------------------------------------------
-------------------------
| Id  | Operation            | Name             | Rows  | Bytes | Cost (%CPU)| T
ime     | Pstart| Pstop |
--------------------------------------------------------------------------------
-------------------------
|   0 | UPDATE STATEMENT     |                  |  2119K|    56M| 30132   (2)| 0
0:06:02 |       |       |
|   1 |  UPDATE              | APPLICATION_DATA |       |       |            |
        |       |       |
|   2 |   PARTITION RANGE ALL|                  |  2119K|    56M| 30132   (2)| 0
0:06:02 |     1 |     5 |
|*  3 |    TABLE ACCESS FULL | APPLICATION_DATA |  2119K|    56M| 30132   (2)| 0
0:06:02 |     1 |     5 |
--------------------------------------------------------------------------------
-------------------------
There is an index on the columns in the where clause, and the funny thing is, when running tkprof, the correct plan is used and the update runs perfectly.  
TKPROF output
UPDATE "DEP"."APPLICATION_DATA"
   SET "SYS_UPDATEDATE" = SYS_EXTRACT_UTC(CURRENT_TIMESTAMP),
       "SYS_SESSIONID" = 0,
        "SYS_STATE" = MYBITAND("SYS_STATE", 18446744073709551613)
 WHERE "SYS_SESSIONID" = :V1
call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.01       0.07          0          3          0           0
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2      0.01       0.07          0          3          0           0
Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: CHOOSE
Parsing user id: 26
Rows     Row Source Operation
-------  ---------------------------------------------------
      0  UPDATE  APPLICATION_DATA (cr=3 pr=0 pw=0 time=1467 us)
      0   INDEX RANGE SCAN APPLICATION_DATA_IDX0 (cr=3 pr=0 pw=0 time=1461 us)(o
bject id 79758)
Is there a way to remove the above plan returned by awr?  I've flushed the sga and bounced instances, but its still being used.
Thanks!
 
 
Function with clob as return
Rajasekhar, October   02, 2020 - 12:00 pm UTC
 
 
Hello Chris,
  i am receiving  “(HUGECLOB)” in toad, when selecting a function that returns clob data type. is it related to tool issue or i am querying a clob datatype wrongly? if yes, how to select  a function that returns clob data type?
Thanks in advance. 
October   05, 2020 - 12:12 am UTC 
 
This is just the way TOAD chooses to let you know there is clob data. Double clicking on normally will then show the data itself.