Как загрузить файл с заданного URL и сохранить его в колонке типа BLOB?

Нужно создать процедуру, которая получит URL как параметр, загрузит файл с этого URL и сохранит его в колонке с типом BLOB.

Какой должен быть подход для достижения этой цели?


Свободный перевод вопроса Procedure to download file from a given url in and save it into the blob type column от участника @Harshit Gupta


Ответы (2 шт):

Автор решения: 0xdb

Самый простой способ, воспользоваться объектным типом HTTPURITYPE:

The HTTPURITYPE is a subtype of the UriType that provides support for the HTTP protocol. This uses the UTL_HTTP package underneath to access the HTTP URLs. Proxy and secure wallets are not supported in this release.

Обеспечивает поддержку протокола HTTP. Использует пакет UTL_HTTP для доступа к URL. Прокси и безопасные кошельки не поддерживаются в этом выпуске.

Простой пример:

create table urlres (url varchar2 (255), data blob, loaded date)
/
create or replace procedure loadbinary (url varchar2) as
    b blob;
begin
    b := httpuritype.createuri (url).getblob();
    insert into urlres values (url, b, sysdate);
end;
/

Запустить и результат:

exec loadbinary ('www.oracle.com/us/hp07-bgf3fafb-db12c-2421053.jpg');

select * from urlres
/
URL                              DATA             LOADED             
-------------------------------- ---------------- -------------------
www.oracle.com/us/hp07-bgf3fafb- FFD8FFE000104A46 2020-10-22 19:15:21
db12c-2421053.jpg                4946000101000001                    
                                 00010000FFDB0084                    
                                 0002020202020203                    
                                 0303030404030404                    
→ Ссылка
Автор решения: 0xdb

Можно воспользоваться пакетом UTL_HTTP. Он поддерживает HTTPS (HTTP через SSL) и авторизацию. Для HTTPS потребуется создать кошелек с Oracle Wallet Manager.

Рабочий пример реализации:

create or replace procedure loadbinary (
    url varchar2, uname varchar2 := null, pass varchar2 := null, 
    walletpath varchar2 := null, walletpass varchar2 := null) as
    req  utl_http.req;
    resp utl_http.resp;
    bl blob;
    rw raw (32767);
begin
    if walletpath is not null and walletpass is not null then
        utl_http.set_wallet ('file:'||walletpath, walletpass);
    end if;

    req := utl_http.begin_request (url);
    if uname is not null and pass is not null then
        utl_http.set_authentication (req, uname, pass);
    end if;
    resp := utl_http.get_response (req);

    dbms_lob.createtemporary(bl, false);
    begin loop
        utl_http.read_raw (resp, rw, 32766);
        dbms_lob.writeappend (bl, utl_raw.length(rw), rw);
    end loop;
    exception when utl_http.end_of_body then
        utl_http.end_response (resp);
    end;
    insert into urlres values (url, bl, sysdate);

    dbms_lob.freetemporary (bl);
exception when others then
    utl_http.end_response (resp);
    dbms_lob.freetemporary (bl);
    raise;
end loadbinary;
/
→ Ссылка