Skip to Main Content
  • Questions
  • Reading Data in Clobs that are > 32767 K

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, Dean.

Asked: April 23, 2002 - 8:42 am UTC

Last updated: April 23, 2006 - 5:29 am UTC

Version: 8.1.7.2.0

Viewed 10K+ times! This question is

You Asked

Hello Tom,

I am faced with the challenge of dealing with CLOB values that are
greater than 32767 characters in length. For example, I have to read a record's CLOB value which has a length = 946056k. When I test the
dbms_lob.read package it fails when the amount is > 32767. If this is
the case, how can one use this function to read the chunks of a CLOB
which has a length > 32767k.

Any help on this will be greatly appreciated.

Thanks,

Dean

DBMS_LOB defines the following constants:
-------------------------------------------------------------------
file_readonly CONSTANT BINARY_INTEGER := 0;
lob_readonly CONSTANT BINARY_INTEGER := 0;

lob_readwrite CONSTANT BINARY_INTEGER := 1;
lobmaxsize CONSTANT INTEGER := 4294967295;
call CONSTANT PLS_INTEGER := 12;
session CONSTANT PLS_INTEGER := 10;
-------------------------------------------------------------------

DBMS_LOB uses the following Parameters:


Parameter Descrption:
-----------------------------------------
lob_loc: Locator for the LOB to be read.
amount: Number of bytes (for BLOBs) or characters (for CLOBs) to read,
or number that were read.
offset: Offset in bytes (for BLOBs) or characters (for CLOBs) from
the start of the LOB (origin: 1).
buffer: Output buffer for the read operation.


Please Note: The following block of code errors out because the amount
is > 32767.

declare
c_text_long varchar2(32767);
lobloc CLOB;
buffer VARCHAR2(32767);
amount number := 4294967295; -- clob max size in
bytes!
offset INTEGER := 100;
lob_length integer := 0;
begin
select text_long
into lobloc
from scopus.notes_clob
where note_id = 147787;

dbms_lob.read(lobloc,amount,offset,buffer);

exception
when others then
dbms_output.put_line('SQLCODE:'||SQLCODE);
dbms_output.put_line('SQLERRM:'||SQLERRM);
end;
/





and Tom said...

PLSQL is limited to 32k -- other languages (C, java, etc) are not.

In PLSQL, you will process the CLOB in chunks, 32k at a time. You will not have a big "in memory variable" is is the string that is the CLOB.


Even in C or Java -- you would not typically do that. Think of the CLOB as you would a file (it is atually built ontop of file libraries). Think of it like you opened a 5 megabyte text file. You would process that file by reading a line, seeking to a position, reading N bytes. Do the same with a LOB.

Rating

  (5 ratings)

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

Comments

Reading Clobs > 32K

Dean Hogan, April 23, 2002 - 10:17 am UTC

Tom, thanks for your prompt response. Would you be able to give me an example of pl/sql code, which processes clobs in 32k chunks?

Tom Kyte
April 23, 2002 - 11:01 am UTC

</code> http://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:711825134415 <code>

it is working on a bfile with RAW data but the concept is the same. use dbms_lob.substr or dbms_lob.read to get the piece you want, process it and do something with it and move onto the next piece.


Returning CLOB

Prashant, April 21, 2006 - 7:08 pm UTC

Hi Tom,

I have a problem returning XML back to my front end application.

My Architecture is like following.

I have stored procedure which generates XML with TAG in a CLOB object. And returns CLOB to the front end application

And the front the application is able to display the data correctly.

But the it fails when i have more data in my CLOB.

Is there any general rule for this.
Front end application is of Java based.


Thanks & Regards
Prashant

Tom Kyte
April 22, 2006 - 3:07 pm UTC

the general rule is

java has no problems with using clobs, therefore your code is likely "incorrect"

given what you've given us to work with here, that is about the most we can say in response

Returning CLOB

Prashant, April 22, 2006 - 11:24 pm UTC

Hi Tom,

Please find the following code which just calls a stored procedure which return a CLOB object.

declare
l_len number;
v_ret_clob CLOB:=' ';

begin
Orcl_Proc_Ctrl_4_Xml.EXECUTE_CONTROL(v_ret_clob);
l_len := dbms_lob.getlength(v_ret_clob);
dbms_output.put_line('the return size OF CLOB------> '||l_len);

end;

Following way i am getting output for above PL/SQL block.

the return size OF CLOB------> 113906

But the above CLOB is not being displayed by front end.

Thanks
Prashant

Tom Kyte
April 23, 2006 - 5:29 am UTC

"sorry"

since "front end" is a rather vague term and could in fact mean just about ANYTHING at all.


you do not give any example to work with here.

Returning CLOB- Solved

Prashant, April 24, 2006 - 8:33 pm UTC

Hi Tom,

Today the Return CLOB was Solved And solution was from Java Front Side.
The developer was using some Read function instead of bufferreader so front end application can now show CLOB more than 32 K.

Thanks a lot

Thanks & Regards
Prashant Pathak

Return of Table Type Record

Prashant Pathak, May 09, 2006 - 2:36 pm UTC

Hi Tom,

I am trying to make one general function which will generate the XML CLOB depending on data given.

What i have?
I have 10 procedure which generates 10 XML CLOB. All 10 XML CLOB has different table type. I mean one table type has 10 column and in another procedure a table type is having 9 column.
so in all 10 procedure i have a common code to popupate the XML CLOB. which looks like

Procedure_1003
.
.
.
for l_counter in 1..1003_tbl.count
loop
dbms_lob.append
( p_out_xml, '<ROW num="'|| l_counter || '">'||'<Operating_Unit_Name>'|| ' ' || 1003_tbl(l_counter).l_operating_unit_name||'</Operating_Unit_Name>' ||'<Inventory_Organization_Code>' || ' '|| 1003_tbl(l_counter).l_inventory_organization_code</Inventory_Organization_Code>' ||
end loop;
.
.
.

Procedure_1004
.
.

for l_counter in 1..1004_tbl.count
loop
dbms_lob.append
( p_out_xml, '<ROW num="'|| l_counter || '">'||'<Operating_Unit_Name>'|| ' ' || 1004_tbl(l_counter).l_operating_unit_name||'</Operating_Unit_Name>' ||'<Inventory_Name>' || ' '|| 1004_tbl(l_counter).l_inventory_Name</Inventory_Name>' ||
||'<Price>' || ' '|| 1004_tbl(l_counter).Price</Price>' ||
end loop;
.
.


so in 10 different procedure i have a bit same code for generating XML.

Now i want to pass the table type to a procedure which can generate the XML CLOB with tag.

in each procedure i have fixed column but across the procedure column varies.
So my difficulties is how to pass these different table type record to a common procedure which can take all these table type record and generate XML CLOB.

Thanks
Prashant

More to Explore

CLOB/BLOB/etc

Complete documentation on Securefiles and Large Objects here