Oracle 我想用这个代码进行批量复制,好吗?

Oracle 我想用这个代码进行批量复制,好吗?,oracle,plsql,oracle9i,Oracle,Plsql,Oracle9i,我认为,如果我能通过无效操作错误,这个将完成一次将所有文件写入目录的工作 一如既往,我们非常感谢你的帮助 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

我认为,如果我能通过无效操作错误,这个将完成一次将所有文件写入目录的工作

一如既往,我们非常感谢你的帮助

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;
为什么要用这个版本替换以前版本的代码?如果已经有一个版本的代码正在向文件系统写入一个BLOB,那么在循环中调用该代码是非常容易的。这也是设计模块化代码的更好方法。 当您收到错误时,请发布错误堆栈。这将包括Oracle错误号、错误消息和错误行号。告诉我们代码中对应的行,特别是当您在此处发布的内容与实际运行的代码之间存在格式差异时。 不能在单个线程中同时将每个LOB复制到文件中。单个线程一次可以做一件事,因此它一次可以复制一个文件。可以循环,以便按顺序复制每个文件。我仍然不清楚这是您想要做的,还是您真的想要生成800个线程,每个线程向文件系统写入一个LOB。 由于在循环中打开文件,因此需要在循环中关闭文件。请注意,保留旧代码将更容易避免此类错误。假设您希望使用表中的文件名,那么在对fopen的调用中应该使用recFiles.file\u name,而不是硬编码字符串“file\u name”,它将尝试将每个LOB写入同一个物理文件。 考虑到这一点,我的猜测是,您需要类似于此注释的内容,它仍然是模块化此代码的更好形式,但由于您试图避免这种情况,我假设您有一个很好的理由

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;
为什么要用这个版本替换以前版本的代码?如果已经有一个版本的代码正在向文件系统写入一个BLOB,那么在循环中调用该代码是非常容易的。这也是设计模块化代码的更好方法。 当您收到错误时,请发布错误堆栈。这将包括Oracle错误号、错误消息和错误行号。告诉我们代码中对应的行,特别是当您在此处发布的内容与实际运行的代码之间存在格式差异时。 不能在单个线程中同时将每个LOB复制到文件中。单个线程一次可以做一件事,因此它一次可以复制一个文件。可以循环,以便按顺序复制每个文件。我仍然不清楚这是您想要做的,还是您真的想要生成800个线程,每个线程向文件系统写入一个LOB。 由于在循环中打开文件,因此需要在循环中关闭文件。请注意,保留旧代码将更容易避免此类错误。假设您希望使用表中的文件名,那么在对fopen的调用中应该使用recFiles.file\u name,而不是硬编码字符串“file\u name”,它将尝试将每个LOB写入同一个物理文件。 考虑到这一点,我的猜测是,您需要类似于此注释的内容,它仍然是模块化此代码的更好形式,但由于您试图避免这种情况,我假设您有一个很好的理由

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;

您想对导出的Blob执行什么操作?您想对导出的Blob执行什么操作?首先感谢您的回复。我已经用更清楚地解释我要做什么的代码替换了原来的代码。如果您查看我刚刚发布的代码,每次运行它时,都会出现无效操作错误。这告诉我,在我所知有限的情况下,我拥有目录名的方式,要么是我没有访问它的权限,要么是目录无法被识别。是的,原稿一次只写一个文件,这很痛苦。我刚刚发布的那个应该同时复制整个文件。你能帮我解决这个无效的操作错误吗?@ChidiOkeh-你为什么要替换原来的代码?如果原始版本能够正确导出单个文件,那么在循环中调用它应该是一个简单的过程,如我所示。如果此版本的代码出现错误,请发布错误堆栈。将有一个Oracle错误号、一条错误消息和一个行号。告诉我们对应的是哪一行。正如我在您的同事在OTN论坛上发布此代码时提到的,您至少需要关闭循环中的文件。每次打开文件时都使用相同的文件名。谢谢你,贾斯汀。请理解,我是一个完全白痴,当谈到甲骨文。我很乐意按照你的建议去做。我只是不知道如何把它们放在一起。如果您仍然希望我发布原始代码以获得您的帮助,我将很乐意这样做。再次感谢您的帮助。我现在就试试。贾斯汀,我得到一个错误,14/49 PLS-00201:标识符'REC_FILES.FILE_
“名称”必须是declared@ChidiOkeh-那是个打字错误。它应该是recFiles,因为这是您命名的游标。我修正了打字错误。首先谢谢你的回复。我已经用更清楚地解释我要做什么的代码替换了原来的代码。如果您查看我刚刚发布的代码,每次运行它时,都会出现无效操作错误。这告诉我,在我所知有限的情况下,我拥有目录名的方式,要么是我没有访问它的权限,要么是目录无法被识别。是的,原稿一次只写一个文件,这很痛苦。我刚刚发布的那个应该同时复制整个文件。你能帮我解决这个无效的操作错误吗?@ChidiOkeh-你为什么要替换原来的代码?如果原始版本能够正确导出单个文件,那么在循环中调用它应该是一个简单的过程,如我所示。如果此版本的代码出现错误,请发布错误堆栈。将有一个Oracle错误号、一条错误消息和一个行号。告诉我们对应的是哪一行。正如我在您的同事在OTN论坛上发布此代码时提到的,您至少需要关闭循环中的文件。每次打开文件时都使用相同的文件名。谢谢你,贾斯汀。请理解,我是一个完全白痴,当谈到甲骨文。我很乐意按照你的建议去做。我只是不知道如何把它们放在一起。如果您仍然希望我发布原始代码以获得您的帮助,我将很乐意这样做。再次感谢您的帮助。贾斯汀,我得到一个错误,14/49 PLS-00201:标识符“REC\u FILES.FILE\u NAME”必须是declared@ChidiOkeh-那是个打字错误。它应该是recFiles,因为这是您命名的游标。我修正了打字错误。