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.