如何将BLOB映像复制到文件系统

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

我在这里被告知过

https://softwareengineering.stackexchange.com/questions/362992/all-images-on-a-single-table-is-a-good-idea/363007#363007

将图像存储在文件系统中,而不是表中的BLOB。

如何将BLOB复制到文件,并获取其路径(由APEX应用程序访问)?

我正在考虑创建一个将BLOB映像保存到文件系统的触发器,并将路径保存到varchar列。

表有一个像这样的结构

CREATE TABLE "ALLIMAGES_TBL" 
   (    "ID" NUMBER NOT NULL ENABLE, 
        "NAME" NVARCHAR2(400), 
        "FILENAME" VARCHAR2(350 BYTE), 
        "MIME_TYPE" VARCHAR2(255 BYTE), 
        "SIZE" NUMBER, 
        "CHARSET" VARCHAR2(128 BYTE), 
        "LAST_UPDATE_DATE" DATE, 
        "BinaryBLOB" BLOB, 
        "PATH" varchar(260), 
sql oracle11g oracle-apex
1个回答
0
投票

像往常一样,两种选择都有赞成和反对:将图像保存在数据库中,或将它们保存在文件系统中。在我看来,如果只有少数(好的,让我们在大约100秒内测量它们),我宁愿把它们放在一张桌子里。处理它们更容易。因为,一旦它们在文件系统中,您将不得不使用更多(HTML)代码在Apex中获取和显示它们。

无论如何,这是我如何做到的(在之前的Apex版本之一,我相信它是4.0):使用“文件浏览”项目我暂时将图像存储到一个表中(它是WWW_FLOW_FILES;你现在宁愿使用自己的表),然后 - 在按下按钮触发的过程中 - 我将它们移动到一个目录中。

流程代码:

declare
  -- l_dest_dir is name of the directory (Oracle object) which points
  -- to a filesystem directory
  l_dest_dir varchar2(30) := pkg_slike.f_dir_slike_upload_dp(:P0_DP);
begin
  for cur_r in (select id, filename 
                from wwv_flow_files
                where upper(filename) like 'TS%.JP%G' 
               )
  loop
    -- put a picture into L_DEST_DIR
    pkg_slike.p_write_blob_to_file(cur_r.id, l_dest_dir);

    delete from wwv_flow_files
      where id = cur_r.id;
  end loop;
end;

程序代码:

   PROCEDURE p_write_blob_to_file (p_file_id IN NUMBER, p_dir IN VARCHAR2)
   IS
      /* 19.04.2012. Taken from Eddie Awad's Blog
                     http://awads.net/wp/2011/09/20/create-an-application-to-upload-files-using-oracle-apex-in-less-than-10-minutes-video/
      */
      l_blob            BLOB;
      l_blob_length     INTEGER;
      l_out_file        UTL_FILE.file_type;
      l_buffer          RAW (32767);
      l_chunk_size      BINARY_INTEGER := 32767;
      l_blob_position   INTEGER := 1;
      l_file_name       pkg_general.subt_ime_slike;
   BEGIN
      -- Retrieve the BLOB for reading
      SELECT blob_content, filename
        INTO l_blob, l_file_name
        FROM wwv_flow_files
       WHERE id = p_file_id;

      -- Retrieve the SIZE of the BLOB
      l_blob_length := DBMS_LOB.getlength (l_blob);

      -- Open a handle to the location where you are going to write the BLOB
      -- to file.
      -- NOTE: The 'wb' parameter means "write in byte mode" and is only
      --       available in the UTL_FILE package with Oracle 10g or later
      l_out_file :=
         UTL_FILE.fopen (p_dir,
                         l_file_name,
                         'wb' -- important. If ony w then extra carriage return/line brake
                             ,
                         l_chunk_size);

      -- Write the BLOB to file in chunks
      WHILE l_blob_position <= l_blob_length
      LOOP
         IF l_blob_position + l_chunk_size - 1 > l_blob_length
         THEN
            l_chunk_size := l_blob_length - l_blob_position + 1;
         END IF;

         DBMS_LOB.read (l_blob,
                        l_chunk_size,
                        l_blob_position,
                        l_buffer);
         UTL_FILE.put_raw (l_out_file, l_buffer, TRUE);
         l_blob_position := l_blob_position + l_chunk_size;
      END LOOP;

      -- Close the file handle
      UTL_FILE.fclose (l_out_file);
   END p_write_blob_to_file;

希望您能够根据自己的情况调整它。

© www.soinside.com 2019 - 2024. All rights reserved.