Получить курсы валют с сайта www.nbrb.by

  • Oracle 11g

На сайте http://www.nbrb.by каждый день обновляются курсы валют для РБ. Курсы валют можно получить в виде XML-файла, если пройти по этой ссылке: http://www.nbrb.by/Services/XmlExRates.aspx?ondate=01/28/2014. Здесь подробное описание структуры XML-файла: http://www.nbrb.by/statistics/Rates/XML/.

Немного о параметрах XML-файла… Параметр ondate – дата в формате месяц/день/год, на которую запрашивается официальный курс. Если параметр ondate не задан, то Вы получите официальный курс на последнюю дату установления.

Каждый элемент Currency содержит атрибут ID (внутренний код валюты – целое число) и вложенные элементы:

  • NumCode – цифровой код
  • CharCode – буквенный код
  • Scale – номинал
  • Name – наименование валюты
  • Rate – курс.

Конечно имеется много способов получения данных из XML-файлов, но рассмотрим случай, когда нужно получить данные из XML-файла с сайта, не сохраняя файл за ранее, чтобы импортировать их в базу.

В Oracle имеются различные методы обработки xml-файлов, мы будем использовать XMLTYPE (функция конструктор позволяющая извлекать и работать с xml-данными, -узлами и -фрагментами), HTTPURITYPE (подтип UriType, который обеспечивает поддержку протокола HTTP, при этом используется пакет UTL_HTTP, чтобы получить доступ к HTTP URL. Прокси и безопасные кошельки не поддерживаются в Oracle 11g) и XMLTable (функция позволяющая запросить результат XQuery, возвращаемый функцией, в виде виртуальной реляционной таблицы, используя SQL).

Так как cтруктура XML-файла и методы работы с XML-данными (XMLTYPE, HTTPURITYPE, XMLTable) известны, можно получить курсы валют:

-- Получаем список курсов валют, которые обновляются ежедневно (update Daily)
SELECT x.VAL_NAME, x.VAL_RATE
FROM (select substr(HTTPURITYPE('http://www.nbrb.by/Services/XmlExRates.aspx?ondate='||to_char(sysdate+1,'MM/DD/YYYY')).getclob(),
regexp_instr(HTTPURITYPE('http://www.nbrb.by/Services/XmlExRates.aspx?ondate='||to_char(sysdate+1,'MM/DD/YYYY')).getclob(),
'<+', 1)) XML_CODE FROM DUAL) t,
XMLTable(
'/DailyExRates/Currency'
passing xmltype(T.XML_CODE)
columns VAL_KOD number path 'NumCode'
, VAL_NAME varchar2(30) path 'CharCode'
, VAL_RATE number path 'Rate'
) x;

-- Получаем список курсов валют, которые обновляются ежемесячно (update Monthly)
SELECT x.VAL_NAME, x.VAL_RATE
FROM (select substr(HTTPURITYPE('http://www.nbrb.by/Services/XmlExRates.aspx?ondate='||to_char(sysdate,'MM/DD/YYYY')||to_char('&')||'period=1').getclob(),
regexp_instr(HTTPURITYPE('http://www.nbrb.by/Services/XmlExRates.aspx?ondate='||to_char(sysdate,'MM/DD/YYYY')||to_char('&')||'period=1').getclob(),
'<+', 1)) XML_CODE FROM DUAL) t,
XMLTable(
'/MonthlyExRates/Currency'
passing xmltype(T.XML_CODE)
columns VAL_KOD number path 'NumCode'
, VAL_NAME varchar2(30) path 'CharCode'
, VAL_RATE number path 'Rate'
) x;

В запросе используются функции SUBSTR, REGEXP_INSTR для удаления скрытых служебных символов, которые влияют на работу функции XMLTYPE.

Чтобы данный запрос работал должен быть разрешен доступ к сайту http://www.nbrb.by с помощью Access Control List (пакет dbms_network_acl_admin) и выданы права на пакет UTL_HTTP.