Tuesday, January 06, 2009

Grabbing a Webpage Greater than 32k using UTL_HTTP

The UTL_HTTP package in Oracle allows PL/SQL to grab a webpage and save it into an Oracle variable. The trouble is, it returns a Varchar2 and this can be up to 32k. The solution is to use the DBMS_LOB package to write to a CLOB. A loop gets the 32k chunks and appends them to the CLOB. Straightforward enough but it takes some time to get it all working. Here's the code:

CREATE OR REPLACE PROCEDURE load_html_from_url (p_url  IN  VARCHAR2, p_html out clob) AS
l_http_request UTL_HTTP.req;
l_http_response UTL_HTTP.resp;
l_clob CLOB;
l_text VARCHAR2(32767);
BEGIN
-- Initialize the CLOB.
DBMS_LOB.createtemporary(l_clob, FALSE);

-- Make a HTTP request and get the response.
l_http_request := UTL_HTTP.begin_request(p_url);
l_http_response := UTL_HTTP.get_response(l_http_request);

-- Copy the response into the CLOB.
BEGIN
LOOP
UTL_HTTP.read_text(l_http_response, l_text, 32767);
DBMS_LOB.writeappend (l_clob, LENGTH(l_text), l_text);
END LOOP;
EXCEPTION
WHEN UTL_HTTP.end_of_body THEN
UTL_HTTP.end_response(l_http_response);
END;

p_html:= l_clob;
EXCEPTION
WHEN OTHERS THEN
UTL_HTTP.end_response(l_http_response);
-- Relase the resources associated with the temporary LOB.
DBMS_LOB.freetemporary(l_clob);
RAISE;
END load_html_from_url;


Note: if you want to use HTTP POST instead of GET, you will need to create your request differently. Use
l_http_request := UTL_HTTP.begin_request(v_url, 'POST', 'HTTP/1.1');
utl_http.write_text(l_http_request, v_message);


It may also be necessary to specify the content length like so:
utl_http.set_header(l_http_request, 'Content-Length', length(v_message));

6 comments:

jmc said...

Thank you for this! I ran into this exact problem - I suspected it was a 32k limit on utl_http.read_text, but your page confirmed it and saved me the trouble of writing the necessary code snippet.

System Trader said...

Same here. This save me lots of time. Thanks for posting this code!!

Hicetubique said...

Guys,

I want to write data which is of size > 32k using UTL_HTTP.WRITE_TEXT. I tried with a clob variable but it is showing numeric or value error. Can anybody help me please?

Peter V said...

Hey Asha,

I haven't tried UTL_HTTP.WRITE_TEXT, but I see on http://psoug.org/reference/utl_http.html that the parameter is a Varchar2. The CLOB is of the wrong type. You would have to read 32k at a time from the CLOB and then find some other way to append to the HTTP data, since it looks like it is stored as a Varchar... There might be some way to send a multipart message...

Adolfo Blanco said...

Thank you very much !!!!

Anonymous said...

Hi,
Need help in concatenating the JSON string rows into single row.

By using PLSQL code we retrieved the HTTP_UTL.RESPONSE from API. Which is returning 32k JSON string for each fetch and inserting into x table which has CLOB datatype.

So, finally i have 7 rows in x table as shown below... each row JSON string length is 32k.
Now i want to concatenate the 7 JSON string rows into single row.



-- 7 JSON string rows form x table..
[{"keys":["PartType","PartClass"],"length":2,"_fields":["SI- Purchased Software","CFI-Software"],"_fieldLookup":{"PartType":0,"PartClass":1}},.....32767
:{"PartType":0,"PartClass":1}},{"keys":["PartType","PartClass"],"length":2,"_fields":["Service Kit,Compact Disk Drive","Assy,Base,Cus,Mod,Ship,.....32767
Class"],"length":2,"_fields":["Kit,Compact Diskette","Assy,Base,Cus,Mod,Ship,Svc"],"_fieldLookup":{"PartType":0,"PartClass":1}},{"keys":["PartT.....32767
Cus,Mod,Ship,Svc"],"_fieldLookup":{"PartType":0,"PartClass":1}},{"keys":["PartType","PartClass"],"length":2,"_fields":["MOD,Instructions","Assy.....32767
ss"],"length":2,"_fields":["CD/Floppy Drive combo","Drive,Combo"],"_fieldLookup":{"PartType":0,"PartClass":1}},{"keys":["PartType","PartClass"].....32767
ype":0,"PartClass":1}},{"keys":["PartType","PartClass"],"length":2,"_fields":["SI- Purchased Floppy Drive","CFI-CSTM FCTRY INTG"],"_fieldLookup.....32767
:0,"PartClass":1}},{"keys":["PartType","PartClass"],"length":2,"_fields":["Socket,PLCC","Socket"],"_fieldLookup":{"PartType":0,"PartClass":1}}] .....4084


---- In other way i tried using below query on x table with above 7 JSON string rows. It is giving in single row but last 7th row is repeating multiple times.


Select Json_Arrayagg( Cont Order By Sno Returning Clob) Json_Data
From x;

Please help....

Labels

Blog Archive

Contributors