我正在使用下面的脚本从MongoDB获取JSON文件,解析它然后将其插入到Oracle表中。
表 Appery_Photos 中的列 Photo 属于CLOB类型,而 DecodedPhoto 列属于BLOB类型。
问题在于我用来将CLOB解码为BLOB的行blobOriginal := base64decode1(Photo);
。函数 base64decode1 已被多个函数替换(即decode_base64,base64DecodeClobAsBlob_plsql,base64decode,from_base64& finally JSON_EXT.DECODE)
结果对所有人来说都是一样的。也就是说,生成的BLOB对象不能作为任何图像编辑器中的图像打开(我使用Oracle SQL Developer下载它)。
我查了CLOB,找不到任何新行 \ n ,也找不到任何空格(只找到+符号)。此外,我将CLOB值插入base64-image-converter并正确显示图像。另外,为了进一步验证(使用上面链接中提供的相反功能),我尝试在base64中编码生成的BLOB,结果base64完全不同。
BEGIN l_http_request := UTL_HTTP.begin_request('https://api.appery.io/rest/1/db/collections/Photos?where=%7B%22Oracle_Flag%22%3A%22Y%22%7D' , 'GET' , 'HTTP/1.1'); -- ...set header's attributes UTL_HTTP.set_header(l_http_request, 'X-Appery-Database-Id', '53f2dac5e4b02cca64021dbe'); l_http_response := UTL_HTTP.get_response(l_http_request); BEGIN LOOP UTL_HTTP.read_text(l_http_response, buf); l_response_text := l_response_text || buf; END LOOP; EXCEPTION WHEN UTL_HTTP.end_of_body THEN NULL; END; l_list := json_list(l_response_text); FOR i IN 1..l_list.count LOOP A_id := json_ext.get_string(json(l_list.get(i)),'_id'); l_val := json_ext.get_json_value(json(l_list.get(i)),'Photo'); dbms_lob.createtemporary(Photo, true, 2); json_value.get_string(l_val, Photo); dbms_output.put_line(dbms_lob.getlength(Photo)); dbms_output.put_line(dbms_lob.substr(Photo, 20, 1)); blobOriginal := base64decode1(Photo); A_Name := json_ext.get_string(json(l_list.get(i)),'Name'); Remarks := json_ext.get_string(json(l_list.get(i)),'Remarks'); Status := json_ext.get_string(json(l_list.get(i)),'Status'); UserId := json_ext.get_string(json(l_list.get(i)),'UserId'); A_Date := json_ext.get_string(json(l_list.get(i)),'Date'); A_Time := json_ext.get_string(json(l_list.get(i)),'Time'); MSG_status := json_ext.get_string(json(l_list.get(i)),'MSG_status'); Oracle_Flag := json_ext.get_string(json(l_list.get(i)),'Oracle_Flag'); acl := json_ext.get_string(json(l_list.get(i)),'acl'); INSERT INTO Appery_Photos ( A_id, Photo, DecodedPhoto, A_Name, Remarks, Status, UserId, A_Date, A_Time, MSG_status , Oracle_Flag, acl ) VALUES ( A_id, Photo, blobOriginal, A_Name, Remarks, Status, UserId, A_Date, A_Time, MSG_status , Oracle_Flag, acl ); dbms_lob.freetemporary(Photo); END LOOP; -- finalizing UTL_HTTP.end_response(l_http_response); EXCEPTION WHEN UTL_HTTP.end_of_body THEN UTL_HTTP.end_response(l_http_response); END;
非常感谢任何帮助。
答案 0 :(得分:0)
我发现这不在我在base64解码中使用的函数中。相反,我拥有的值不是base64编码的字符串,而是base64编码dataURi,类似
数据:图像/ JPEG; BASE64,/ 9J / 4AAQSkZJRgABAQAAA
所以我必须使用类似:clobbase642blob(substr(Photo,instr(Photo,',')+ 1))
以下脚本的灵感来自Oracle Community回答
DECLARE l_param_list VARCHAR2(512); l_http_request UTL_HTTP.req; l_http_response UTL_HTTP.resp; l_response_text CLOB; --l_response_text VARCHAR2(32767); buf VARCHAR2(32767); l_list json_list; l_val json_value; A_id VARCHAR2(100); Photo CLOB; A_Name VARCHAR2(100); Remarks VARCHAR2(100); Status VARCHAR2(100); UserId VARCHAR2(100); A_Date VARCHAR2(100); A_Time VARCHAR2(100); MSG_status VARCHAR2(100); Oracle_Flag VARCHAR2(100); acl VARCHAR2(100); obj json_list; blobOriginal BLOB := empty_blob(); clobInBase64 CLOB; substring VARCHAR2(2000); tmp BLOB; n pls_integer := 0; substring_length pls_integer := 2000; ------------------------------------------------------ FUNCTION clobbase642blob( p_clob CLOB ) RETURN BLOB IS t_blob BLOB; t_buffer VARCHAR2(32767); t_pos NUMBER := 1; t_size NUMBER := nls_charset_decl_len( 32764, nls_charset_id( 'char_cs' ) ); t_len NUMBER; t_tmp raw(32767); BEGIN dbms_lob.createtemporary( t_blob, true ); t_len := LENGTH( p_clob ); LOOP EXIT WHEN t_pos > t_len; t_buffer := REPLACE( REPLACE( SUBSTR( p_clob, t_pos, t_size ), chr(10) ), chr(13) ); t_pos := t_pos + t_size; WHILE t_pos 0 LOOP t_buffer := t_buffer || REPLACE( REPLACE( SUBSTR( p_clob, t_pos, 1 ), chr(10) ), chr(13) ); t_pos := t_pos + 1; END LOOP; t_tmp := utl_encode.base64_decode( utl_raw.cast_to_raw( t_buffer ) ); dbms_lob.writeappend( t_blob, utl_raw.length( t_tmp ), t_tmp ); END LOOP; RETURN t_blob; END; ------------------------------------------------------ BEGIN -- service's input parameters -- preparing Request... l_http_request := UTL_HTTP.begin_request('https://api.appery.io/rest/1/db/collections/Photos?where=%7B%22Oracle_Flag%22%3A%22Y%22%7D' , 'GET' , 'HTTP/1.1'); -- ...set header's attributes UTL_HTTP.set_header(l_http_request, 'X-Appery-Database-Id', '53f2dac5e4b02cca64021dbe'); l_http_response := UTL_HTTP.get_response(l_http_request); BEGIN LOOP UTL_HTTP.read_text(l_http_response, buf); l_response_text := l_response_text || buf; END LOOP; EXCEPTION WHEN UTL_HTTP.end_of_body THEN NULL; END; l_list := json_list(l_response_text); FOR i IN 1..l_list.count LOOP A_id := json_ext.get_string(json(l_list.get(i)),'_id'); --deal with base64 URI photo >32KB l_val := json_ext.get_json_value(json(l_list.get(i)),'Photo'); dbms_lob.createtemporary(Photo, true, 2); json_value.get_string(l_val, Photo); --dbms_output.put_line(dbms_lob.getlength(Photo)); --dbms_output.put_line(dbms_lob.substr(Photo, 20, 1)); blobOriginal := clobbase642blob( SUBSTR( Photo, 24 ) ); A_Name := json_ext.get_string(json(l_list.get(i)),'Name'); Remarks := json_ext.get_string(json(l_list.get(i)),'Remarks'); Status := json_ext.get_string(json(l_list.get(i)),'Status'); UserId := json_ext.get_string(json(l_list.get(i)),'UserId'); A_Date := json_ext.get_string(json(l_list.get(i)),'Date'); A_Time := json_ext.get_string(json(l_list.get(i)),'Time'); MSG_status := json_ext.get_string(json(l_list.get(i)),'MSG_status'); Oracle_Flag := json_ext.get_string(json(l_list.get(i)),'Oracle_Flag'); acl := json_ext.get_string(json(l_list.get(i)),'acl'); INSERT INTO Appery_Photos ( A_id, Photo, DecodedPhoto, A_Name, Remarks, Status, UserId, A_Date, A_Time, MSG_status , Oracle_Flag, acl ) VALUES ( A_id, Photo, blobOriginal, A_Name, Remarks, Status, UserId, A_Date, A_Time, MSG_status , Oracle_Flag, acl ); dbms_lob.freetemporary(Photo); END LOOP; -- finalizing UTL_HTTP.end_response(l_http_response); EXCEPTION WHEN UTL_HTTP.end_of_body THEN UTL_HTTP.end_response(l_http_response); END; /
答案 1 :(得分:0)
它是Base64或HexBinary ...
这适用于HexBinary
function DESERIALIZE_HEX_BLOB(P_SERIALIZATION CLOB)
return BLOB
is
V_BLOB BLOB;
V_OFFSET INTEGER := 1;
V_AMOUNT INTEGER := 32000;
V_INPUT_LENGTH NUMBER := DBMS_LOB.GETLENGTH(P_SERIALIZATION);
V_HEXBINARY_DATA VARCHAR2(32000);
begin
if (P_SERIALIZATION is NULL) then return NULL; end if;
DBMS_LOB.CREATETEMPORARY(V_BLOB,TRUE,DBMS_LOB.CALL);
while (V_OFFSET <= V_INPUT_LENGTH) loop
V_AMOUNT := 32000;
DBMS_LOB.READ(P_SERIALIZATION,V_AMOUNT,V_OFFSET,V_HEXBINARY_DATA);
V_OFFSET := V_OFFSET + V_AMOUNT;
DBMS_LOB.APPEND(V_BLOB,TO_BLOB(HEXTORAW(V_HEXBINARY_DATA)));
end loop;
return V_BLOB;
end;
--
可以很容易地修改它以处理Base64。