El Banco Central Europeo dispone de un webservice en donde publica el cambio diario de divisas del Euro a otras divisas, para acceder a esa información se dispone de esta URL: http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml
En este ejemplo se busca obtener de forma muy simple mediante una SELECT la lista de divisas y su correspondiente cambio.
SELECT EXTRACTVALUE (value (tab), '/Cube/@currency',
'xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref') currency,
EXTRACTVALUE (value (tab), '/Cube/@rate',
'xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref') rate
FROM TABLE(XMLSEQUENCE(EXTRACT(
pk_xml.lee_xml_desde_url('http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml', null, null),
'/gesmes:Envelope/Cube/Cube/Cube',
'xmlns:gesmes=http://www.gesmes.org/xml/2002-08-01 xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref"'
))) tab;
Autorizar dirección
Este punto es necesario en caso de tener Oracle 11 o superior. Hay que autorizar la dirección www.ebc.europa.eu de la siguiente forma:
DECLARE
acl_path VARCHAR2 (4000);
v_numero NUMBER;
BEGIN
SELECT acl
INTO acl_path
FROM dba_network_acls
WHERE HOST = 'www.ecb.europa.eu'
AND lower_port IS NULL
AND upper_port IS NULL;
IF dbms_network_acl_admin.check_privilege (acl_path, USER, 'connect') IS NULL THEN
dbms_network_acl_admin.add_privilege (acl_path, USER, TRUE, 'connect');
END IF;
COMMIT;
EXCEPTION
WHEN NO_DATA_FOUND THEN
SELECT COUNT(*)
INTO v_numero
FROM dba_network_acls
WHERE acl LIKE '%ACL_LIBRA.xml%';
IF v_numero = 0 THEN
dbms_network_acl_admin.create_acl ('ACL_LIBRA.xml', 'Permisos TCP usuario LIBRA', USER, TRUE, 'connect');
END IF;
dbms_network_acl_admin.assign_acl ('ACL_LIBRA.xml', 'www.ecb.europa.eu');
COMMIT;
END;
/
En caso de no hacerlo nos dará el siguiente error:
ORA-29273: fallo de la solicitud HTTP
ORA-06512: en «SYS.UTL_HTTP», línea 1130
ORA-24247: acceso de red denegado por la lista de control de acceso (ACL)
ORA-06512: en «LIBRA.PK_XML», línea 148
Función PK_XML.LEE_XML_DESDE_URL
El paqute PK_XML forma parte del entorno de Libra, y su código es el siguiente:
FUNCTION lee_xml_desde_url(p_url VARCHAR2, p_usuario VARCHAR2, p_password VARCHAR2) RETURN XMLTYPE AS
/* Descarga un xml de una dirección web que se pasa por parámetro "p_url".
Si la dirección web requiere autentificación se debe de pasar el usuario y la constraseña en
p_usuario y p_password */
v_req UTL_HTTP.req;
resp UTL_HTTP.resp;
my_scheme VARCHAR2(256);
my_realm VARCHAR2(256);
my_proxy BOOLEAN;
name VARCHAR2(4000);
v_valor VARCHAR2(32000);
v_clob CLOB;
v_xml XMLTYPE;
v_resultado VARCHAR2(30) := 'OK';
BEGIN
v_req := UTL_HTTP.begin_request(p_url);
UTL_HTTP.set_transfer_timeout(180);
IF p_usuario IS NOT NULL THEN
UTL_HTTP.set_authentication(v_req, p_usuario, p_password);
END IF;
resp := UTL_HTTP.get_response(v_req);
IF (resp.status_code = UTL_HTTP.http_unauthorized) THEN
UTL_HTTP.get_authentication(resp, my_scheme, my_realm, my_proxy);
IF (my_proxy) THEN
v_resultado := 'PROXY';
DBMS_OUTPUT.put_line('Web proxy server is protected.');
DBMS_OUTPUT.put('Please supplied the required ' || my_scheme || ' authentication username/password for realm ' || my_realm || ' for the proxy server.');
ELSE
v_resultado := 'VALIDACION';
DBMS_OUTPUT.put_line('Web page ' || p_url || ' is protected.');
DBMS_OUTPUT.put('Please supplied the required ' || my_scheme || ' authentication username/password for realm ' || my_realm || ' for the Web page.');
END IF;
UTL_HTTP.end_response(resp);
v_resultado := 'ERROR';
END IF;
IF v_resultado = 'OK' THEN
FOR i IN 1 .. UTL_HTTP.get_header_count(resp) LOOP
UTL_HTTP.get_header(resp, i, name, v_valor);
DBMS_OUTPUT.put_line(name || ': ' || v_valor);
END LOOP;
LOOP
BEGIN
UTL_HTTP.read_text(resp, v_valor, 30000);
v_clob := v_clob || v_valor;
DBMS_OUTPUT.put_line(v_valor);
EXCEPTION
WHEN OTHERS THEN
EXIT;
END;
END LOOP;
v_xml := xmltype.createxml(v_clob);
UTL_HTTP.end_response(resp);
END IF;
RETURN (v_xml);
END;


