Я хотел бы выполнить BULK копию с этим кодом, пожалуйста? - PullRequest
1 голос
/ 15 ноября 2011

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

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

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 голос
/ 15 ноября 2011
  1. Почему вы заменили предыдущую версию кода этой версией? Если у вас уже есть версия кода, которая работает для записи одного большого двоичного объекта в файловую систему, очень просто вызвать этот код в цикле. Это также лучший способ разработки модульного кода.
  2. Когда вы получаете сообщение об ошибке, пожалуйста, оставьте сообщение об ошибке. Это будет включать номер ошибки Oracle, сообщение об ошибке и номер строки ошибки. Сообщите нам, какой строке соответствует ваш код (особенно, если есть различия в форматировании между тем, что вы публикуете здесь, и тем, какой код вы на самом деле выполняете).
  3. Вы не можете в одном потоке копировать каждый большой объект в файл одновременно. Один поток может делать одну вещь за раз, поэтому он может копировать один файл за раз. Вы можете выполнить цикл, чтобы копировать каждый файл последовательно. Мне все еще неясно, хотите ли вы именно этого или действительно хотите порождать 800 потоков, каждый из которых записывает один большой объект в файловую систему.
  4. Вам необходимо закрыть файл внутри цикла, поскольку вы открываете файл в цикле (обратите внимание, что сохранение старого кода значительно облегчит предотвращение ошибок такого рода). И, предполагая, что вы хотите использовать имя файла из таблицы, вы захотите использовать 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;
...