The approach for Oracle 9iR2 and 10g – based on the supplied UTL_HTTP package .
This article demonstrates a rather generic approach – which I think must be very close to using the UTL_DBWS package. We will take a more pragmatic, to the point line of action – that amounts to the same thing. Another resource that came in handy: Oracle Database 10g – XML & SQL: Design, Build & Manage XML Applications in Java,C, C++ & PL/SQL, Mark Scardina, Ben Chang and Jinyu Wang, Oracle Press – McGrawHill Osborne; 2004; ISBN 0-07-222952-7.
We know what the SOAP messages look like. Now we will create a PL/SQL block that recreates the SOAP message and then invokes the proper UTL_HTTP command:
declare
soap_request varchar2(30000);
soap_respond varchar2(30000);
http_req utl_http.req;
http_resp utl_http.resp;
resp XMLType;
i integer;
begin
soap_request:= '
us
uk
';
http_req:= utl_http.begin_request
( 'http://services.xmethods.net:80/soap'
, 'POST'
, 'HTTP/1.1'
);
utl_http.set_header(http_req, 'Content-Type', 'text/xml'); -- since we are dealing with plain text in XML documents
utl_http.set_header(http_req, 'Content-Length', length(soap_request));
utl_http.set_header(http_req, 'SOAPAction', ''); -- required to specify this is a SOAP communication
utl_http.write_text(http_req, soap_request);
http_resp:= utl_http.get_response(http_req);
utl_http.read_text(http_resp, soap_respond);
utl_http.end_response(http_resp);
resp:= XMLType.createXML(soap_respond);
resp:= resp.extract('/soap:Envelop/soap:Body/child::node()'
, 'xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"'
);
i:=0;
loop
dbms_output.put_line(substr(soap_respond,1+ i*255,250));
i:= i+1;
if i*250> length(soap_respond)
then
exit;
end if;
end loop;
end;
The output from runnning this piece of PL/SQL in SQL*Plus is this
0.5342
Turning this PL/SQL block into a proper PL/SQL Function that accepts the two countries as input-parameters is straightforward:
function get_conversion_rate
( p_country1 in varchar2 default 'us'
, p_country2 in varchar2 default 'us'
)
return varchar2
as
soap_request varchar2(30000);
soap_respond varchar2(30000);
http_req utl_http.req;
http_resp utl_http.resp;
resp XMLType;
begin
soap_request:= '
'||p_country1||'
'||p_country2||'
';
http_req:= utl_http.begin_request
( 'http://services.xmethods.net:80/soap'
, 'POST'
, 'HTTP/1.1'
);
utl_http.set_header(http_req, 'Content-Type', 'text/xml');
utl_http.set_header(http_req, 'Content-Length', length(soap_request));
utl_http.set_header(http_req, 'SOAPAction', '');
utl_http.write_text(http_req, soap_request);
http_resp:= utl_http.get_response(http_req);
utl_http.read_text(http_resp, soap_respond);
utl_http.end_response(http_resp);
- - Create an XMLType variable containing the Response XML
resp:= XMLType.createXML(soap_respond);
- - extract from the XMLType Resp the child-nodes of the element
resp:= resp.extract('/soap:Envelope/soap:Body/child::node()'
, 'xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"'
);
- - extract from the XMLType Resp the text() nodes from the n:getRateResponse/Result element
resp:= resp.extract('n:getRateResponse/Result/text()','xmlns:n="urn:xmethods-CurrencyExchange"');
return resp.getClobVal();
end;
We can create this function in any schema that has access to the sys.UTL_HTTP package. Calling this Function can be done from PL/SQL or even SQL:
select get_conversion_rate('uk','us')
from dual
/
GET_CONVERSION_RATE('UK','US')
---------------------------------
1.8713

Recent Comments