使用 PL/SQL HTTP 上传 BLOB 文件
Upload BLOB files using PL/SQL HTTP
通常,我使用下面的结构来发送POST请求,内容为varchar2和数字..等等
content := '{"Original File Name":"'||V_HOMEBANNER_1_EN_NAME(indx)||'"}';
url := 'https://api.appery.io/rest/1/db/Names';
req := utl_http.begin_request(url, 'POST',' HTTP/1.1');
UTL_HTTP.set_header(req, 'X-Appery-Database-Id', '5f2dac54b02cc6402dbe');
utl_http.set_header(req, 'content-type', 'application/json');
UTL_HTTP.set_header(req, 'X-Appery-Session-Token', sessionToken);
utl_http.set_header(req, 'Content-Length', LENGTH(content));
utl_http.write_text(req, content);
res := utl_http.get_response(req);
BEGIN
LOOP
utl_http.read_line(res, buffer);
END LOOP;
utl_http.end_response(res);
EXCEPTION
WHEN utl_http.end_of_body THEN
utl_http.end_response(res);
END;
而且效果很好。但是,现在我想 send/upload 一个 blob 文件(jpg 图像)变成一些 MongoDB collection 称为 'Files' (所以 url := ttps:// api.appery.io/rest/1/db/Files). collection 指南有以下 cURL 作为一般建议:
curl -X POST \
-H "X-Appery-Database-Id: 5f2dac54b02cc6402dbe" \
-H "X-Appery-Session-Token: <session_token>" \
-H "Content-Type: <content_type>" \
--data-binary '<file_content>' \
https://api.appery.io/rest/1/db/files/<file_name>
但我无法将此 cURL 翻译成 PL/SQL 请求。具体来说,部分 (--data-binary '')
我在 Oracle table 中有这些 BLOB 文件,它们的存储名称如下:
+-----------+--------------+
| File_Name | File_content |
+-----------+--------------+
| PIC_1.jpg | BLOB |
| PIC_2.jpg | BLOB |
| PIC_3.jpg | BLOB |
+-----------+--------------+
我的问题,如何将这些图片上传到目标URL?
受到@JeffreyKemp 建议的 blog 的启发,我通过仅将 write_text()
替换为 write_raw()
来工作,以便将内容正文作为 BLOB 发送(由 API).
以下代码是我的函数的关键部分,需要进行更改:
content := V_HOMEBANNER_1_EN(indx);
file_name := 'test.jpg';
url := 'https://api.appery.io/rest/1/db/files/'||file_name;
req := utl_http.begin_request(url, 'POST',' HTTP/1.1');
UTL_HTTP.set_header(req, 'X-Appery-Database-Id', '53fae4b02cc4021dbe');
UTL_HTTP.set_header(req, 'X-Appery-Session-Token', sessionToken);
utl_http.set_header(req, 'content-type', 'image/jpeg');
req_length := DBMS_LOB.getlength(CONTENT);
DBMS_OUTPUT.PUT_LINE(req_length);
--IF MSG DATA UNDER 32KB LIMIT:
IF req_length <= 32767
THEN
begin
utl_http.set_header(req, 'Content-Length', req_length);
utl_http.write_raw(req, content);
exception
when others then
DBMS_OUTPUT.PUT_LINE(sqlerrm);
end;
--IF MSG DATA MORE THAN 32KB
ELSIF req_length >32767
THEN
BEGIN
DBMS_OUTPUT.PUT_LINE(req_length);
utl_http.set_header(req, 'Transfer-Encoding', 'Chunked');
WHILE (offset < req_length)
LOOP
DBMS_LOB.read(content, amount, offset, buffer);
utl_http.write_raw(req, buffer);
offset := offset + amount;
END LOOP;
exception
when others then
DBMS_OUTPUT.PUT_LINE(sqlerrm);
end;
END IF;
l_http_response := UTL_HTTP.get_response(req);
UTL_HTTP.read_text(l_http_response, response_body, 32767);
UTL_HTTP.end_response(l_http_response);
尝试和测试大于和小于 32KB images/jpg。
通常,我使用下面的结构来发送POST请求,内容为varchar2和数字..等等
content := '{"Original File Name":"'||V_HOMEBANNER_1_EN_NAME(indx)||'"}';
url := 'https://api.appery.io/rest/1/db/Names';
req := utl_http.begin_request(url, 'POST',' HTTP/1.1');
UTL_HTTP.set_header(req, 'X-Appery-Database-Id', '5f2dac54b02cc6402dbe');
utl_http.set_header(req, 'content-type', 'application/json');
UTL_HTTP.set_header(req, 'X-Appery-Session-Token', sessionToken);
utl_http.set_header(req, 'Content-Length', LENGTH(content));
utl_http.write_text(req, content);
res := utl_http.get_response(req);
BEGIN
LOOP
utl_http.read_line(res, buffer);
END LOOP;
utl_http.end_response(res);
EXCEPTION
WHEN utl_http.end_of_body THEN
utl_http.end_response(res);
END;
而且效果很好。但是,现在我想 send/upload 一个 blob 文件(jpg 图像)变成一些 MongoDB collection 称为 'Files' (所以 url := ttps:// api.appery.io/rest/1/db/Files). collection 指南有以下 cURL 作为一般建议:
curl -X POST \
-H "X-Appery-Database-Id: 5f2dac54b02cc6402dbe" \
-H "X-Appery-Session-Token: <session_token>" \
-H "Content-Type: <content_type>" \
--data-binary '<file_content>' \
https://api.appery.io/rest/1/db/files/<file_name>
但我无法将此 cURL 翻译成 PL/SQL 请求。具体来说,部分 (--data-binary '')
我在 Oracle table 中有这些 BLOB 文件,它们的存储名称如下:
+-----------+--------------+ | File_Name | File_content | +-----------+--------------+ | PIC_1.jpg | BLOB | | PIC_2.jpg | BLOB | | PIC_3.jpg | BLOB | +-----------+--------------+
我的问题,如何将这些图片上传到目标URL?
受到@JeffreyKemp 建议的 blog 的启发,我通过仅将 write_text()
替换为 write_raw()
来工作,以便将内容正文作为 BLOB 发送(由 API).
以下代码是我的函数的关键部分,需要进行更改:
content := V_HOMEBANNER_1_EN(indx);
file_name := 'test.jpg';
url := 'https://api.appery.io/rest/1/db/files/'||file_name;
req := utl_http.begin_request(url, 'POST',' HTTP/1.1');
UTL_HTTP.set_header(req, 'X-Appery-Database-Id', '53fae4b02cc4021dbe');
UTL_HTTP.set_header(req, 'X-Appery-Session-Token', sessionToken);
utl_http.set_header(req, 'content-type', 'image/jpeg');
req_length := DBMS_LOB.getlength(CONTENT);
DBMS_OUTPUT.PUT_LINE(req_length);
--IF MSG DATA UNDER 32KB LIMIT:
IF req_length <= 32767
THEN
begin
utl_http.set_header(req, 'Content-Length', req_length);
utl_http.write_raw(req, content);
exception
when others then
DBMS_OUTPUT.PUT_LINE(sqlerrm);
end;
--IF MSG DATA MORE THAN 32KB
ELSIF req_length >32767
THEN
BEGIN
DBMS_OUTPUT.PUT_LINE(req_length);
utl_http.set_header(req, 'Transfer-Encoding', 'Chunked');
WHILE (offset < req_length)
LOOP
DBMS_LOB.read(content, amount, offset, buffer);
utl_http.write_raw(req, buffer);
offset := offset + amount;
END LOOP;
exception
when others then
DBMS_OUTPUT.PUT_LINE(sqlerrm);
end;
END IF;
l_http_response := UTL_HTTP.get_response(req);
UTL_HTTP.read_text(l_http_response, response_body, 32767);
UTL_HTTP.end_response(l_http_response);
尝试和测试大于和小于 32KB images/jpg。