Если обращение в интернет будет осуществляться через приближенный (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.