Oracle 提取表中所有记录的BLOB内容
我目前有一个超过150000条记录的表。每份记录都附有一份简历。我当前的项目要求我将BLOB列中存储的所有简历提取到文件系统上的一个文件夹中 我根据我发现的一个示例创建了一个过程,该示例允许我提取一条记录,但我不知道如何让它在每个记录中循环并提取所有文件,一旦我删除where子句中的记录标识符,该过程就会因错误而失败Oracle 提取表中所有记录的BLOB内容,oracle,plsql,Oracle,Plsql,我目前有一个超过150000条记录的表。每份记录都附有一份简历。我当前的项目要求我将BLOB列中存储的所有简历提取到文件系统上的一个文件夹中 我根据我发现的一个示例创建了一个过程,该示例允许我提取一条记录,但我不知道如何让它在每个记录中循环并提取所有文件,一旦我删除where子句中的记录标识符,该过程就会因错误而失败 ERROR at line 1: ORA-01422: exact fetch returns more than requested number of rows ORA-065
ERROR at line 1:
ORA-01422: exact fetch returns more than requested number of rows
ORA-06512: at "SYS.WRITE_BLOB_TO_FILE", line 17
ORA-06512: at line 1
如果有人对这件事有任何见解,我会非常感激
我在下面使用的程序
CREATE OR REPLACE PROCEDURE Write_BLOB_To_File
AS
v_lob_loc BLOB;
v_filename VARCHAR2(255);
v_buffer RAW(32767);
v_buffer_size BINARY_INTEGER;
v_amount BINARY_INTEGER;
v_offset NUMBER(38) := 1;
v_chunksize INTEGER;
v_out_file UTL_FILE.FILE_TYPE;
BEGIN
SELECT cobrokes.subs.resume, cobrokes.subs.filename
INTO v_lob_loc, v_filename
FROM cobrokes.subs;
v_chunksize := DBMS_LOB.GETCHUNKSIZE(v_lob_loc);
IF (v_chunksize < 32767) THEN
v_buffer_size := v_chunksize;
ELSE
v_buffer_size := 32767;
END IF;
v_amount := v_buffer_size;
DBMS_LOB.OPEN(v_lob_loc, DBMS_LOB.LOB_READONLY);
v_out_file := UTL_FILE.FOPEN(
location => 'LOB_DIR',
filename => v_filename,
open_mode => 'wb',
max_linesize => 32767);
WHILE v_amount >= v_buffer_size
LOOP
DBMS_LOB.READ(
lob_loc => v_lob_loc,
amount => v_amount,
offset => v_offset,
buffer => v_buffer);
v_offset := v_offset + v_amount;
UTL_FILE.PUT_RAW (
file => v_out_file,
buffer => v_buffer,
autoflush => true);
UTL_FILE.FFLUSH(file => v_out_file);
END LOOP;
UTL_FILE.FFLUSH(file => v_out_file);
UTL_FILE.FCLOSE(v_out_file);
DBMS_LOB.CLOSE(v_lob_loc);
END;
/
错误很简单,您无法将多行提取到单个对象中。试着这样做:-
create or replace type blob_obj_handlr is table of BLOB;
/
create or replace type char_obj_handlr is table of varchar2(100);
/
然后像这样执行查询
lv_b_resume :=blob_obj_handlr();
lv_v_filenm :=char_obj_handlr();
EXECUTE IMMEDIATE ('SELECT cobrokes.subs.resume, cobrokes.subs.filename
FROM cobrokes.subs') BULK COLLECT into lv_b_resume,lv_v_filenm;
我设法解决了这个问题,我将把这个留给其他需要完成这个任务的人
CREATE OR REPLACE PROCEDURE Write_BLOB_To_File
AS
v_blob BLOB;
v_start NUMBER := 1;
v_bytelen NUMBER := 32767;
v_len NUMBER;
v_raw RAW (32767);
v_x NUMBER;
v_output UTL_FILE.file_type;
v_filename VARCHAR2 (255);
v_pkey NUMBER;
BEGIN
FOR i IN (SELECT DBMS_LOB.getlength (RESUME) v_len, FILENAME v_filename,
RESUME v_blob, PKEY v_pkey
FROM COBROKES.SUBS)
LOOP
v_output := UTL_FILE.fopen ('LOB_DIR', i.v_pkey || '-' || i.v_filename || chr(0), 'wb', 32767);
v_x := i.v_len;
v_start := 1;
v_bytelen := 32767;
WHILE v_start < i.v_len AND v_bytelen > 0
LOOP
DBMS_LOB.READ (i.v_blob, v_bytelen, v_start, v_raw);
UTL_FILE.put_raw (v_output, v_raw);
UTL_FILE.fflush (v_output);
v_start := v_start + v_bytelen;
v_x := v_x - v_bytelen;
IF v_x < 2000
THEN
v_bytelen := v_x;
END IF;
END LOOP;
UTL_FILE.fclose (v_output);
END LOOP;
END Write_BLOB_To_File;
/
v_filename是表的列,其中包含BLOB列中文件的文件名,v_pkey是表中的主键列,我知道该列最常用ID
这个脚本的输出将文件名保存在pkey filename结构中,在我的例子中是“102 some file name.docx”,原因是我们需要bable将文档追溯到表中的记录,使用主键是最简单的方法
希望这能帮助其他需要完成这项工作的人
CREATE OR REPLACE PROCEDURE Write_BLOB_To_File
AS
v_blob BLOB;
v_start NUMBER := 1;
v_bytelen NUMBER := 32767;
v_len NUMBER;
v_raw RAW (32767);
v_x NUMBER;
v_output UTL_FILE.file_type;
v_filename VARCHAR2 (255);
v_pkey NUMBER;
BEGIN
FOR i IN (SELECT DBMS_LOB.getlength (RESUME) v_len, FILENAME v_filename,
RESUME v_blob, PKEY v_pkey
FROM COBROKES.SUBS)
LOOP
v_output := UTL_FILE.fopen ('LOB_DIR', i.v_pkey || '-' || i.v_filename || chr(0), 'wb', 32767);
v_x := i.v_len;
v_start := 1;
v_bytelen := 32767;
WHILE v_start < i.v_len AND v_bytelen > 0
LOOP
DBMS_LOB.READ (i.v_blob, v_bytelen, v_start, v_raw);
UTL_FILE.put_raw (v_output, v_raw);
UTL_FILE.fflush (v_output);
v_start := v_start + v_bytelen;
v_x := v_x - v_bytelen;
IF v_x < 2000
THEN
v_bytelen := v_x;
END IF;
END LOOP;
UTL_FILE.fclose (v_output);
END LOOP;
END Write_BLOB_To_File;
/
对不起,这不是我的强项,我该如何将其应用到我现有的程序中?