Базы данных Oracle - статьи

         

Получаем документ из Интернета


Если обращение в интернет будет осуществляться через приближенный (proxy) сервер, требуется предварительно выдать что-то вроде:

EXECUTE UTL_HTTP.SET_PROXY ('http://имя:пароль@адрес:порт')

Для извлечения документа из интернета мне очень хотелось бы воспользоваться типом HTTPURITYPE, но проверка показывает, что этот тип не способен посылать запросы HTTP методом POST, а для нашей страницы, как опять-таки показывает проверка, требуется именно это. Притом, страница динамическая: обратите внимание на завершение адреса текстом ?rssid=rss_otn_news. (Несложная проверка параметров ответа при обращении по этому адресу показывает, что получателем запроса является сервлет на Oracle Application Server). Поэтому придется прибегнуть к пакету UTL_HTTP и программированию.

Для удобства занесем основную часть адреса и параметры в переменные SQL*Plus:

VARIABLE url VARCHAR2 ( 1000 ) VARIABLE parameters VARCHAR2 ( 1000 ) VARIABLE length VARCHAR2 ( 1000 )

EXECUTE :url := - 'http://www.oracle.com/technology/pub/articles/hunter_rac10gr2_iscsi.html' EXECUTE :parameters := 'rssid=rss_otn_news' EXECUTE :length := '18'

Для простоты количество символов в подстроке параметров (18) я посчитал вручную.

Заведем переменную SQL*Plus для хранения документа:

VARIABLE htmlclob CLOB EXECUTE :htmlclob := EMPTY_CLOB ( )

При работе учтите, что значение переменной SQL*Plus типа CLOB потеряется, как только вы завершите сеанс связи с СУБД, например в результате выдачи CONNECT. (В действительности, переменная HTMLCLOB есть переменная-«локатор», указывающий на временный LOB-объект со временем жизни сеанса; этот-то LOB-объект и пропадает без нашей воли по завершению сеанса, после чего локатор начнет указывать «в никуда»).

Следующий блок на PL/SQL прочтет по нужному адресу в интернете документ и разместит его в переменной SQL*Plus:

DECLARE req UTL_HTTP.REQ; resp UTL_HTTP.RESP; name VARCHAR2 ( 256 ); value VARCHAR2 ( 4000 );

BEGIN req := UTL_HTTP.BEGIN_REQUEST ( :url, method => 'POST' ); UTL_HTTP.SET_HEADER ( r => req, name => 'Content-Type', value => 'text/html' ); UTL_HTTP.SET_HEADER ( r => req, name => 'Content-Length', value => :length ); UTL_HTTP.WRITE_LINE ( r => req, data => :parameters ); resp := UTL_HTTP.GET_RESPONSE ( req );

DBMS_OUTPUT.PUT_LINE ( 'HTTP response status code: ' resp.status_code ); DBMS_OUTPUT.PUT_LINE ( 'HTTP response reason: ' resp.reason_phrase );

LOOP UTL_HTTP.READ_LINE ( resp, value, TRUE ); :htmlclob := :htmlclob value; END LOOP;

EXCEPTION WHEN UTL_HTTP.END_OF_BODY THEN UTL_HTTP.END_RESPONSE ( resp ); END; /

Выдача на экран добавлена для контроля. Проверить, что документ действительно прочитался, можно, например, так:

CTX> EXECUTE DBMS_OUTPUT.PUT_LINE ( DBMS_LOB.GETLENGTH ( :htmlclob ) ) 166426

PL/SQL procedure successfully completed.

При желании можно было пометить документ в таблицу, но здесь довольно и оставить его в переменной SQL*Plus.



Содержание раздела