如何将Oracle列中的Blob写入文件系统

问题描述 投票:3回答:1

my_images表由一个名为images的blob列组成。我需要将这些图像写入我的image_dir,即'C:\ TEMP'。

执行以下PL / SQL代码时,只将第一个图像作为图像写入目录。第二个blob写为0字节(空),没有其他(总数应为8)。

所以循环似乎不能正常工作。我正在使用Oracle 11g Express Edition(XE)和SQL Developer。这是错误和代码:

Error starting at line : 53 in command -
BEGIN write_blob_to_file_v5; END;
Error report -
ORA-01403: no data found
ORA-06512: at "SYS.DBMS_LOB", line 1056
ORA-06512: at "SYS.WRITE_BLOB_TO_FILE_V5", line 40
ORA-06512: at line 1
01403. 00000 -  "no data found"
*Cause:    No data was found from the objects.
*Action:   There was no data from the objects which may be due to end of fetch.

PL / SQL代码

CREATE OR REPLACE PROCEDURE write_blob_to_file_v5
AS
   v_lob_image_name   VARCHAR (100);
   v_lob_image_id     NUMBER;
   v_blob             BLOB;
   v_buffer           RAW (32767);
   v_buffer_size      BINARY_INTEGER;
   v_amount           BINARY_INTEGER;
   v_offset           NUMBER (38) := 1;
   v_chunksize        INTEGER;
   v_out_file         UTL_FILE.file_type;
BEGIN
   FOR i IN (SELECT DBMS_LOB.getlength (v_blob) v_len,
                    image_id v_lob_image_id,
                    "IMAGE_NAME" v_lob_image_name,
                    image v_blob
               FROM sys.MY_IMAGES)
   LOOP
      v_chunksize := DBMS_LOB.getchunksize (i.v_blob);

      IF (v_chunksize < 32767)
      THEN
         v_buffer_size := v_chunksize;
      ELSE
         v_buffer_size := 32767;
      END IF;

      v_amount := v_buffer_size;
      DBMS_LOB.open (i.v_blob, DBMS_LOB.lob_readonly);
      v_out_file :=
         UTL_FILE.fopen (
            location       => 'IMAGE_DIR',
            filename       => (   ''
                               || i.v_lob_image_id
                               || '_'
                               || i.v_lob_image_name
                               || '.JPG'),
            open_mode      => 'wb',
            max_linesize   => 32767);

      WHILE v_amount >= v_buffer_size
      LOOP
         DBMS_LOB.read (i.v_blob,
                        v_amount,
                        v_offset,
                        v_buffer);
         v_offset := v_offset + v_amount;
         UTL_FILE.put_raw (file        => v_out_file,
                           buffer      => v_buffer,
                           autoflush   => TRUE);
         UTL_FILE.fflush (file => v_out_file);
      --utl_file.new_line(file => v_out_file);
      END LOOP;

      UTL_FILE.fflush (v_out_file);
      UTL_FILE.fclose (v_out_file);
      DBMS_LOB.close (i.v_blob);
   END LOOP;
END;
sql oracle stored-procedures plsql oracle11gr2
1个回答
1
投票

主要问题是NOTre-initialize相关的参数v_offset1(如声明部分所述):

v_offset := 1;

对于之前的每个图像ID

v_chunksize := dbms_lob.getchunksize(i.v_blob); 

分配。

此外,可能会出现尚未关闭或已经打开的blob的问题。为了防止这些,

更换

dbms_lob.open(i.v_blob,dbms_lob.lob_readonly);

if ( dbms_lob.isopen(i.v_blob)=0 ) then
 dbms_lob.open(i.v_blob,dbms_lob.lob_readonly); 
end if;

更换

dbms_lob.close(i.v_blob);

if ( dbms_lob.isopen(i.v_blob)=1 ) then 
 dbms_lob.close(i.v_blob); 
end if;
© www.soinside.com 2019 - 2024. All rights reserved.