PL/SQL解码图片存入Oracle数据库失败,SQL Developer报解码错误
问题解决:Image could not be decoded from the binary stream
核心问题
前端传递的原图是浏览器临时Blob URL(格式如blob:https://domain/xxx),而非图片的base64或二进制数据,PL/SQL错误地将该URL当作base64字符串解码,导致存储的是无效二进制数据,最终无法解析。
修复步骤
1. 前端修改:传递原图的Base64数据而非Blob URL
修改前端处理原图的逻辑,直接将原图的base64字符串(而非Blob URL)赋值给P8_IMAGE_BEFORE_RESIZING:
reader.onload = function (e) { let base64data = e.target.result; console.log('base64data', base64data); // 直接使用base64数据传给后端,不再生成Blob URL作为参数 apex.item("P8_IMAGE_BEFORE_RESIZING").setValue(base64data); console.log("P8_IMAGE_BEFORE_RESIZING", apex.item("P8_IMAGE_BEFORE_RESIZING").getValue()) // 预览原图仍可生成Blob URL,不影响后端逻辑 let binaryString = convertDataURIToBinary(base64data); let blob = new Blob([binaryString], { type: file.type }); let urlCreator = window.URL || window.webkitURL; let imageUrl = urlCreator.createObjectURL(blob); $(notResizeImage).attr('src', imageUrl); $('.imageBeforeResizing').append(notResizeImage); $('.imageBeforeResizing').hide(); }
2. PL/SQL修改:统一处理Base64转Blob逻辑
现在原图和压缩图都是标准的base64格式(带data:image/xxx;base64,前缀),复用压缩图的解码逻辑处理原图即可:
DECLARE l_base64_str CLOB; l_base64_str_before_resize CLOB; l_blob BLOB; l_blob_before_resize BLOB; BEGIN -- 处理压缩图:提取base64核心部分并解码为Blob l_base64_str := SUBSTR(:P8_RESIZED_IMAGE, INSTR(:P8_RESIZED_IMAGE, ',') + 1); l_blob := Utl_Encode.Base64_Decode(UTL_RAW.cast_to_raw(l_base64_str)); -- 处理原图:同样提取base64核心部分并解码为Blob l_base64_str_before_resize := SUBSTR(:P8_IMAGE_BEFORE_RESIZING, INSTR(:P8_IMAGE_BEFORE_RESIZING, ',') + 1); l_blob_before_resize := Utl_Encode.Base64_Decode(UTL_RAW.cast_to_raw(l_base64_str_before_resize)); -- 插入数据,直接使用解码后的Blob对象 INSERT INTO UPLOAD_IMAGES ( ID, IMAGE_BEFORE, IMAGE_AFTER, LATITUDE, LONGITUDE, ALTITUDE, FILENAME, MIMETYPE, DATETIME, RESIZED_IMAGE, EXIF, GEOMETRY ) VALUES ( UPLOAD_IMAGES_SEQ.nextval, l_blob_before_resize, l_blob, :P8_LATITUDE, :P8_LONGITUDE, :P8_ALTITUDE, :P8_FILENAME, :P8_MIMETYPE, sysdate, l_base64_str, :P8_EXIF, SDO_GEOMETRY(2001, 4326, SDO_POINT_TYPE(:P8_LONGITUDE, :P8_LATITUDE, :P8_ALTITUDE), NULL, NULL) ); COMMIT; apex_json.open_object; apex_json.write('success', true); apex_json.close_object; END;
额外优化建议
- 移除PL/SQL中原先处理Blob URL的冗余代码(
v_blob_url、v_raw、v_binary等变量及相关逻辑),简化代码结构。 - 前端可考虑使用
FormData直接传递二进制文件,替代base64格式,减少数据传输体积;PL/SQL端可通过APEX_APPLICATION文件项或UTL_RAW工具处理二进制数据。
内容的提问来源于stack exchange,提问作者Ioanna
相关产品推荐
相关产品推荐

