如何无需创建包仅用SQL语句从Oracle导出含bbl_fic列的BLOB数据?
无需创建包,用单条PL/SQL语句导出BLOB数据
当然可以做到!不需要创建永久包,用匿名PL/SQL块就能完成(可以当作一条语句执行),不过需要先满足几个前提:
- 你的数据库用户有
UTL_FILE权限 - DBA已经帮你创建了一个数据库目录对象(用来映射服务器上的物理路径),并且给你授予了该目录的读写权限
具体操作步骤
- 先确认目录对象(如果还没有,联系DBA执行类似命令):
-- DBA执行:创建目录对象,映射到服务器上的某个路径 CREATE DIRECTORY EXPORT_DIR AS '/opt/oracle/export_files'; -- DBA执行:给你的用户授予读写权限 GRANT READ, WRITE ON DIRECTORY EXPORT_DIR TO your_username;
- 执行这条匿名PL/SQL块(替换成你的表名、过滤条件和输出文件名):
DECLARE v_blob BLOB; v_file UTL_FILE.FILE_TYPE; v_buffer RAW(32767); v_amount BINARY_INTEGER := 32767; v_pos INTEGER := 1; BEGIN -- 替换成你的查询,获取要导出的BLOB SELECT bbl_fic INTO v_blob FROM your_table WHERE id = 123; -- 这里的条件改成你要导出的记录 -- 打开文件,第一个参数是目录对象名,第二个是输出文件名,第三个是写入模式 v_file := UTL_FILE.FOPEN('EXPORT_DIR', 'my_blob_file.bin', 'wb', 32767); -- 分块读取BLOB并写入文件(避免内存溢出) WHILE v_pos <= DBMS_LOB.GETLENGTH(v_blob) LOOP DBMS_LOB.READ(v_blob, v_amount, v_pos, v_buffer); UTL_FILE.PUT_RAW(v_file, v_buffer, TRUE); v_pos := v_pos + v_amount; END LOOP; UTL_FILE.FCLOSE(v_file); EXCEPTION WHEN OTHERS THEN -- 异常时确保文件关闭 IF UTL_FILE.IS_OPEN(v_file) THEN UTL_FILE.FCLOSE(v_file); END IF; RAISE; END; /
注意事项
- 这个方法是把BLOB导出到数据库服务器的目录下,如果你需要弄到本地客户端,得从服务器上拷贝这个文件
- 如果你的BLOB很小(比如几MB以内),也可以用SQL*Plus直接导出到客户端本地,不过有大小限制:
SET LONG 1000000 SET LONGCHUNKSIZE 32767 SET PAGESIZE 0 SET FEEDBACK OFF SET HEAD OFF SPOOL C:\your_local_path\small_blob.bin SELECT UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR(bbl_fic, 32767, 1)) FROM your_table WHERE your_condition; SPOOL OFF
- 如果没有
UTL_FILE权限,也可以联系DBA开通,这是最稳妥的大BLOB导出方式
内容的提问来源于stack exchange,提问作者Y.op
相关产品推荐
相关产品推荐

