基于PL/SQL实现文件上传:编译报错求助
问题排查:ORDS文件上传PL/SQL编译错误
错误原因
编译报错PLS-00382: 表达式类型错误出现在第6行l_blob BLOB := :body;,核心问题是绑定变量:body的类型与BLOB不匹配——ORDS中直接POST的二进制内容通常以RAW类型传递,无法直接赋值给BLOB变量。
解决方案
1. 修正变量类型转换逻辑
将:body的RAW类型内容转换为BLOB,修改后的代码如下:
DECLARE l_file UTL_FILE.FILE_TYPE; l_buffer RAW(32767); l_amount BINARY_INTEGER := 32767; l_pos INTEGER := 1; l_body_raw RAW(32767); l_blob BLOB; -- l_file_name VARCHAR2 (100) := :fileName; l_blob_len INTEGER; l_reqid NUMBER; BEGIN -- 初始化临时BLOB存储上传内容 DBMS_LOB.createtemporary(l_blob, TRUE); l_body_raw := :body; -- 将RAW内容写入BLOB DBMS_LOB.writeappend(l_blob, UTL_RAW.length(l_body_raw), l_body_raw); l_blob_len := DBMS_LOB.getlength(l_blob); -- 打开目标文件(确保XX_FILE目录已授权) l_file := UTL_FILE.fopen('XX_FILE','XX_FILE_NAME.csv','wb', 32767); -- 分块读取BLOB并写入文件 WHILE l_pos <= l_blob_len LOOP DBMS_LOB.read(l_blob, l_amount, l_pos, l_buffer); UTL_FILE.put_raw(l_file, l_buffer, TRUE); l_pos := l_pos + l_amount; END LOOP; -- 关闭文件并释放临时BLOB UTL_FILE.fclose(l_file); DBMS_LOB.freetemporary(l_blob); HTP.P('File Upload Success'); EXCEPTION WHEN OTHERS THEN -- 异常处理:关闭文件+释放临时BLOB IF UTL_FILE.is_open(l_file) THEN UTL_FILE.fclose(l_file); END IF; IF DBMS_LOB.istemporary(l_blob) THEN DBMS_LOB.freetemporary(l_blob); END IF; HTP.P('Error: ' || SQLERRM); END;
2. 确认目录权限
确保XX_FILE目录已在数据库中创建,且当前执行ORDS的用户拥有读写权限:
-- 创建目录(需DBA权限执行) CREATE DIRECTORY XX_FILE AS '/path/to/your/target/directory'; -- 授予读写权限 GRANT READ, WRITE ON DIRECTORY XX_FILE TO your_ords_exec_user;
3. 可选:启用动态文件名
如果需要使用上传的原始文件名,取消注释l_file_name变量,并修改UTL_FILE.fopen的第二个参数:
l_file_name VARCHAR2 (100) := :fileName; -- ... l_file := UTL_FILE.fopen('XX_FILE', l_file_name,'wb', 32767);
内容的提问来源于stack exchange,提问作者uditjain
相关产品推荐
相关产品推荐

