Я хотел бы выполнить BULK копию с этим кодом, пожалуйста?

Я думаю, что этот сделает всю работу по записи всех файлов в каталог сразу, если я смогу преодолеть "ошибку недопустимой операции"

Ваша помощь, как всегда, очень ценится.

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', '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;
     End Loop;
      dbms_output.put_line('End');
      utl_file.fclose(l_output);
END GetFile;

1 ответ

Решение
  1. Почему вы заменили предыдущую версию кода этой версией? Если у вас уже есть версия кода, которая работает для записи одного большого двоичного объекта в файловую систему, очень просто вызвать этот код в цикле. Это также лучший способ разработки модульного кода.
  2. Когда вы получаете сообщение об ошибке, пожалуйста, опубликуйте стек ошибок. Это будет включать номер ошибки Oracle, сообщение об ошибке и номер строки ошибки. Скажите нам, какой строке соответствует ваш код (особенно, если есть различия в форматировании между тем, что вы публикуете здесь, и тем, какой код вы на самом деле выполняете).
  3. Вы не можете в одном потоке копировать каждый большой объект в файл одновременно. Один поток может делать одну вещь за раз, поэтому он может копировать один файл за раз. Вы можете выполнить цикл, чтобы копировать каждый файл последовательно. Мне все еще неясно, хотите ли вы именно этого или действительно хотите порождать 800 потоков, каждый из которых записывает один большой объект в файловую систему.
  4. Вам нужно закрыть файл внутри цикла, так как вы открываете файл в цикле (обратите внимание, что сохранение старого кода значительно облегчит предотвращение ошибок такого рода). И предполагая, что вы хотите использовать имя файла из таблицы, вы хотите использовать recFiles.file_name в вашем звонке fopenа не жестко запрограммированная строка 'имя_файла', которая будет пытаться записать каждый большой объект в один и тот же физический файл.

Учитывая это, я предполагаю, что вы хотите что-то подобное (обратите внимание, что было бы лучше использовать модульный код для этого кода, но, поскольку вы пытаетесь избежать этого, я предполагаю, что у вас есть для этого веские причины)

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;
Другие вопросы по тегам