Hi Oracle,
CREATE TABLE XMLISSUE
(
xmltablecolumn clob
);
Created a table
As shown below code I have inserted some data to clob
DECLARE
XMLCLOB clob;
BEGIN
SELECT XMLTYPE(
DBMS_XMLGEN.GETXML(q'{SELECT * FROM whse_detail e WHERE ROWNUM <= 10000 }')
).getclobval() as data1 INTO XMLCLOB
FROM DUAL;
-- SELECT XMLCLOB FROM DUAL;
-- DBMS_OUTPUT.PUT_LINE(XMLCLOB);
INSERT INTO XMLISSUE(XMLTABLECOLUMN) VALUES(XMLCLOB);
-- SELECT LENGTHB(XMLTABLECOLUMN) AS AASDF
--FROM XMLISSUE;
END;
SELECT XMLTABLECOLUMN AS xmlclob
FROM XMLISSUE;
XMLISSUE is my table having clob type column.That column is having more than 10 MB text/data.
I need to fetch less than 5MB data from that clob.
How can I do it..??
Thank you in advance..
You can use functions in DBMS_LOB to find the length of a clob and substring it:
drop table t purge;
create table t (
x clob
);
declare
tmp clob;
str varchar2(32767) := lpad('x', 32767, 'x');
begin
dbms_lob.createtemporary(tmp,true);
for i in 1 .. 200 loop
dbms_lob.writeappend(tmp,length(str),str);
end loop;
insert into t values (tmp);
end;
/
select dbms_lob.getlength(x) from t;
DBMS_LOB.GETLENGTH(X)
6,553,400
select dbms_lob.getlength(dbms_lob.substr(x, 4000, 1)) from t;
DBMS_LOB.GETLENGTH(DBMS_LOB.SUBSTR(X,4000,1))
4,000
http://docs.oracle.com/cd/E11882_01/appdev.112/e40758/d_lob.htm#ARPLS600 But there's a problem with this approach. Dbms_lob.substr returns a varchar2. In SQL the maximum length of this is 4,000 bytes*. So if you attempt to return strings longer than this you get an error:
select dbms_lob.substr(x, 4001, 1) from t;
SQL Error: ORA-06502: PL/SQL: numeric or value error: character string buffer too small
The limit of varchar2 in PL/SQL is 32k. So you can extract larger strings, but still not the 5Mb you're looking for:
declare
subs varchar2(32767);
tclob clob;
begin
select x
into tclob
from t;
subs := dbms_lob.substr(tclob, 32767, 1);
dbms_output.put_line('Clob length: ' || dbms_lob.getlength(subs));
end;
/
PL/SQL procedure successfully completed.
Clob length: 32767
declare
subs clob;
tclob clob;
begin
select x
into tclob
from t;
subs := dbms_lob.substr(tclob, 32768, 1);
dbms_output.put_line('Clob length: ' || dbms_lob.getlength(subs));
end;
/
PL/SQL procedure successfully completed.
Clob length:
So how to get around this?
Make repeated calls to dbms_lob.substr in PL/SQL!
declare
len pls_integer;
tclob clob;
subc clob;
begin
select x
into tclob
from t;
for i in 0 .. 99 loop
subc := subc || dbms_lob.substr(tclob, 32767, (32767*i) +1);
end loop;
dbms_output.put_line('Clob length: ' || dbms_lob.getlength(subc));
end;
/
PL/SQL procedure successfully completed.
Clob length: 3276700
Note: When processing clobs, the functions work on the number of characters. This is fine if you're sure the strings only use single byte characters. But if your text can contain multi-byte characters, fetching the substring of 5*1024^2 could exceed 5Mb. If 5Mb is a hard limit you could convert the clob to a blob. Then substr works on number of bytes. Be aware: if the last character is multi-byte, it may incorrectly chop it into two!
*In 12.1 this is increased to 32,767 if you're using extended data types.