- Почему вы заменили предыдущую версию кода этой версией? Если у вас уже есть версия кода, которая работает для записи одного большого двоичного объекта в файловую систему, очень просто вызвать этот код в цикле. Это также лучший способ разработки модульного кода.
- Когда вы получаете сообщение об ошибке, пожалуйста, оставьте сообщение об ошибке. Это будет включать номер ошибки Oracle, сообщение об ошибке и номер строки ошибки. Сообщите нам, какой строке соответствует ваш код (особенно, если есть различия в форматировании между тем, что вы публикуете здесь, и тем, какой код вы на самом деле выполняете).
- Вы не можете в одном потоке копировать каждый большой объект в файл одновременно. Один поток может делать одну вещь за раз, поэтому он может копировать один файл за раз. Вы можете выполнить цикл, чтобы копировать каждый файл последовательно. Мне все еще неясно, хотите ли вы именно этого или действительно хотите порождать 800 потоков, каждый из которых записывает один большой объект в файловую систему.
- Вам необходимо закрыть файл внутри цикла, поскольку вы открываете файл в цикле (обратите внимание, что сохранение старого кода значительно облегчит предотвращение ошибок такого рода). И, предполагая, что вы хотите использовать имя файла из таблицы, вы захотите использовать
recFiles.file_name
при вызове fopen
, а не жестко запрограммированную строку «file_name», которая будет пытаться записать каждый большой объект в один и тот же физический файл.
Учитывая это, я предполагаю, что вы хотите что-то вроде этого (обратите внимание, что для модульной формы этого кода все равно будет лучше, но поскольку вы пытаетесь избежать этого, я предполагаю, что у вас есть для этого веские причины)
create or replace
PROCEDURE GetbFile
IS
l_output utl_file.file_type;
vstart NUMBER := 1;
bytelen NUMBER := 32000;
x NUMBER;
my_vr RAW(32000);
v_name VARCHAR2(32760);
BEGIN
FOR recFiles IN (SELECT dbms_lob.getlength(BLOB_VALUE) as len,
FILE_NAME,
BLOB_VALUE from Gfile)
LOOP
l_output := utl_file.fopen('THE_DIR', recFiles.file_name||'.dot', 'w', 32760);
IF recFiles.len < 32760 THEN
utl_file.put_raw(l_output, recFiles.BLOB_VALUE);
utl_file.fflush(l_output);
ELSE -- write in pieces
vstart := 1;
WHILE vstart < recFiles.len
LOOP
dbms_lob.read(recFiles.BLOB_VALUE, bytelen, vstart, my_vr);
utl_file.put_raw(l_output, my_vr);
utl_file.fflush(l_output);
-- set the start position for the next cut
vstart := vstart + bytelen;
-- set the end position if less than 32000 bytes
x := x - bytelen;
IF x < 32000 THEN
bytelen := x;
END IF;
END LOOP;
END IF;
utl_file.fclose(l_output);
End Loop;
dbms_output.put_line('End');
END GetFile;