You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 10:49:59