使用Oracle SQL Developer将BLOB从表导出到目录

使用Oracle SQL Developer将BLOB从表导出到目录,oracle,plsql,oracle11g,blob,oracle-sqldeveloper,Oracle,Plsql,Oracle11g,Blob,Oracle Sqldeveloper,我的任务是编写一个脚本,从Oracle11g数据库表中导出BLOB,大约有14000个。我安装了最新版本的SQL Developer,可以连接到数据库 我的背景是MSSQL,因此这是一段相当长的学习曲线!经过大量的谷歌搜索、流汗、眼泪和喝茶之后,我终于拼凑出了两个脚本来完成这项工作,使用光标在images表中迭代,使用脚本将BLOB从该表导出到一个目录 脚本1的基础-导出BLOB的- 脚本2的基础-使用游标- 尽管我认为这可能会很慢,但我的计算表明,导出14000张图像大约需要11个小时 脚本在

我的任务是编写一个脚本,从Oracle11g数据库表中导出BLOB,大约有14000个。我安装了最新版本的SQL Developer,可以连接到数据库

我的背景是MSSQL,因此这是一段相当长的学习曲线!经过大量的谷歌搜索、流汗、眼泪和喝茶之后,我终于拼凑出了两个脚本来完成这项工作,使用光标在images表中迭代,使用脚本将BLOB从该表导出到一个目录

脚本1的基础-导出BLOB的- 脚本2的基础-使用游标-

尽管我认为这可能会很慢,但我的计算表明,导出14000张图像大约需要11个小时

脚本在表中循环,然后有一个二级循环通过BLOB本身,所以我猜这可以改进吗

我遇到了一个问题,utl_文件进程锁定了正在导出的文件,但是在BLOB导出循环之后插入utl_file.fclose似乎可以解决除最后一个导出的文件之外的所有问题

记住,说到甲骨文,我完全是个新手

我从中导出的表是缩放图像 BLOB字段称为Image 我还导出了列ID、ImageDate和ImageID,并将.jpg作为文件名的一部分追加

我试着写一些评论,以防有人在以后遇到这个问题。这里的脚本,任何帮助或意见将不胜感激

SET serveroutput on                     --Set to output to query window for this session ONLY

CREATE OR REPLACE DIRECTORY TEMPDIR     --Sets the export directory
AS 'C:\TEMP\IMAGES\';


DECLARE                                 --Declare a series of variables
t_blob BLOB;
t_len NUMBER;
t_file_name VARCHAR2(1000);
t_output UTL_FILE.FILE_TYPE;
t_TotalSize NUMBER;
t_position NUMBER := 1;
t_chucklen NUMBER := 4096;
t_chuck RAW(4096);
t_remain NUMBER;


BEGIN                                   --Begin the initial loop

  FOR var_a IN                          --Set the name of the cursor to be used
  (                                     --Define the cursor's properties
    SELECT id, imagedate, imageid
    FROM images
    WHERE imageid IS NOT NULL
    ORDER BY imageid
  )
  LOOP                                  --export loop

  BEGIN                                 --Set the variables to be blank or 0
  --t_blob BLOB;
  t_len := 0;
  t_file_name := '';
  --t_output UTL_FILE.FILE_TYPE;
  t_TotalSize := 0;
  t_position  := 1;
  t_chucklen  := 4096;
  --t_chuck := (4096);
  t_remain := 0; 

      -- Get length of blob
      SELECT DBMS_LOB.GETLENGTH (image), TO_CHAR (id)  || '-' || TO_CHAR (imagedate) || TO_CHAR (imageid) || '.jpg'
      INTO t_TotalSize, t_file_name
      FROM images
      WHERE imageid = var_a.imageid;

      t_remain := t_TotalSize;
      t_output := UTL_FILE.FOPEN ('TEMPDIR', t_file_name, 'wb', 32760);

      -- Get BLOB
      SELECT image
      INTO t_blob 
      FROM images
      WHERE imageid= var_a.imageid;

      -- Retrieving BLOB
      WHILE t_position < t_TotalSize
        LOOP
        DBMS_LOB.READ (t_blob, t_chucklen, t_position, t_chuck);
        UTL_FILE.PUT_RAW (t_output, t_chuck);
        UTL_FILE.FFLUSH (t_output);
        t_position := t_position + t_chucklen;
        t_remain := t_remain - t_chucklen;
          IF t_remain < 4096
            THEN
            t_chucklen := t_remain;
          END IF;

        END LOOP;
        UTL_FILE.FCLOSE (t_output);     --Close each file once it has been exported

      END;  

  END LOOP;

END;

/

因为你在工具中,我们有工具来做你想要的事情-不需要代码…如果你感兴趣,请告诉我代码对我来说很好,我只想到一件事,那就是t_chuck的大小,为什么是4096?请尝试32767,并将t_chucklen修改为32767,这可能会减少内部循环的迭代次数。感谢J91321,我将尝试一下!t_chuck和t_chucklen值只是原始脚本的副本。因为你在工具中,我们有工具来做你想要的事情-不需要代码…如果你感兴趣,请告诉我代码对我来说很好,我只想到一件事,那就是t_chuck的大小,为什么是4096?请尝试32767,并将t_chucklen修改为32767,这可能会减少内部循环的迭代次数。感谢J91321,我将尝试一下!t_chuck和t_chucklen值只是原始脚本的副本。