我正在尝试编写一个plsql过程,以便从另一个系统中的给定url下载文件。此系统需要用户ID和密码才能访问。当我尝试以下过程(基本上是这个脚本)时,我得到了一个错误:
ORA-06502:PL/SQL:数字或值错误:十六进制到原始转换错误
它来自这条线路:utl_http.set_header(l_http_request, 'Authorization', 'Basic ' || utl_encode.base64_encode('userid:passwd'));
我添加它是为了传递凭据。
如果我评论它,这个错误会消失,但我得到:Authorization Required.This server could not verify that you are authorized to access the document requested."
程序代码为:
CREATE OR REPLACE PROCEDURE APPS.load_binary_from_url (p_url IN VARCHAR2) AS
l_http_request UTL_HTTP.req;
l_http_response UTL_HTTP.resp;
l_blob BLOB;
l_raw RAW(32767);
l_url VARCHAR2(300);
BEGIN
-- Initialize the BLOB.
DBMS_LOB.createtemporary(l_blob, FALSE);
l_url :=p_url;
-- Make a HTTP request and get the response.
l_http_request := UTL_HTTP.begin_request(l_url);
utl_http.set_header(l_http_request, 'Authorization', 'Basic ' || utl_encode.base64_encode('userid:passwd'));
l_http_response := UTL_HTTP.get_response(l_http_request);
-- Copy the response into the BLOB.
BEGIN
LOOP
UTL_HTTP.read_raw(l_http_response, l_raw, 32767);
DBMS_LOB.writeappend (l_blob, UTL_RAW.length(l_raw), l_raw);
END LOOP;
EXCEPTION
WHEN UTL_HTTP.end_of_body THEN
UTL_HTTP.end_response(l_http_response);
END;
-- Insert the data into the table.
INSERT INTO http_blob_test (id, url, data)
VALUES (http_blob_test_seq.NEXTVAL, p_url, l_blob);
COMMIT;
-- Relase the resources associated with the temporary LOB.
DBMS_LOB.freetemporary(l_blob);
EXCEPTION
WHEN OTHERS THEN
UTL_HTTP.end_response(l_http_response);
DBMS_LOB.freetemporary(l_blob);
RAISE;
END load_binary_from_url;
/
utl_encode.base64_encode
函数采用RAW参数,而不是VARCHAR2,因此必须首先转换值。您可以在普通SQL:中看到相同的内容(但消息略有不同)
select utl_encode.base64_encode('userid:passwd') from dual;
SQL Error: ORA-01465: invalid hex number
您可以使用utl_i18n.string_to_raw
函数将字符串转换为RAW:
select utl_encode.base64_encode(utl_i18n.string_to_raw('userid:passwd', 'AL32UTF8'))
from dual;
UTL_ENCODE.BASE64_ENCODE(UTL_I18N.STRING_TO_RAW('USERID:PASSWD','AL32UTF8'))
--------------------------------------------------------------------------------
64584E6C636D6C6B4F6E426863334E335A413D3D
取决于您的客户端和设置,这些设置可能显示为如上所述,或者隐式显示为从原始转换回;例如SQL Fiddle将其显示为CCD_ 5。但将其连接起来会使其处于原始形式。
您需要另一个步骤来显式转换为可用的字符串值:
select utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_i18n.string_to_raw('userid:passwd', 'AL32UTF8'))) from dual;
UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(UTL_I18N.STRING_TO_RAW('USERID
--------------------------------------------------------------------------------
dXNlcmlkOnBhc3N3ZA==
并且随后当与CCD_ 6前缀连接时保留相同的值。
你可以在你的程序中做同样的事情:
utl_http.set_header(l_http_request, 'Authorization',
'Basic ' || utl_raw.cast_to_varchar2(utl_encode.base64_encode(
utl_i18n.string_to_raw('userid:passwd', 'AL32UTF8'))));
可选地将RAW值首先存储在它们自己的变量中以便于易读。
我今天遇到了同样的问题,使用解决了这个问题
utl_http.set_header(l_http_request, 'Authorization',
'Basic ' || utl_raw.cast_to_varchar2(utl_encode.base64_encode(
utl_i18n.string_to_raw('userid:passwd', 'UTF8'))));
注意:我使用的是Oracle数据库EE 11GR2