我目前有一张包含150,000条记录的表。每条记录都附有简历。我当前的项目要求将存储在BLOB列中的所有简历提取到文件系统上的文件夹中。
我基于一个示例创建了一个过程,该示例使我可以提取1条记录,但是一旦删除了其中的记录标识符,我就无法弄清楚如何遍历每条记录并提取所有文件。该过程的where子句因错误而失败。
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;
/
答案 0 :(得分:1)
错误很简单-您无法将多个行提取到单个对象中。尝试这样:-
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;
然后执行这样的查询
Settings
答案 1 :(得分:0)
设法弄清楚了,我把这个留给需要完成此任务的其他人。
v_filename是表的列,其中包含BLOB列中文件的文件名,而v_pkey是表中的主键列(我知道该列使用最多的ID)。
此脚本的输出将文件名带有文件名的文件保存在pkey-filename结构中,在我的情况下为“ 102-some-file-name.docx”,原因是我们需要能够跟踪将文档返回表中的记录并使用主键只是最简单的方法。
希望这可以帮助需要完成此任务的其他人。
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;
/