通过APEX从数据库服务器下载文件

时间:2020-07-22 14:30:03

标签: oracle plsql apex

我正在尝试找到一种通过APEX从数据库服务器获取文件的方法。我找不到有关此问题的任何文档。 我可以避免使用plsql代码吗?

PS:我正在db所在的另一台服务器上的tomcat上启动APEX。

1 个答案:

答案 0 :(得分:1)

当我们谈论评论时,让我给您看一个例子。我给你写了很多东西,所以花点时间...

上传文件

您可以在Apex中拥有一个对象,该对象允许用户浏览要上传的文件。最后,用户按下触发动作的按钮。按钮上传将提交页面,并且操作将在按钮本身提交之后进行。任何上传的文件都会自动存储在apex_application_temp_files中(请记住,我删除了很多有关文件格式,大小等的控件)。

enter image description here 首先创建目录

create or replace directory yourdirectory as '/your_path' ;
grant read, write on directory yourdirectory to your_user ;

按钮中的代码:

declare 
v_error       VARCHAR2(400);
v_filename    VARCHAR2(400);
v_name        VARCHAR2(400);
v_blob        blob; 
vodate        number(8);
begin
   
    SELECT filename,blob_content,name, to_number(regexp_replace(filename,'[0-9]{4}[0-9]{2}[0-9]{2}')) 
    INTO v_filename,v_blob,v_name,vodate
    FROM apex_application_temp_files
    WHERE name = :P2_FILE;
    
    apex_debug.enable ( p_level => 5 );
    apex_debug.message(p_message => 'v_filename is '||v_filename||' ', p_level => 5) ;
    apex_debug.message(p_message => 'v_name is '||v_name||' ', p_level => 5) ;
    apex_debug.message(p_message => 'vodate is '||to_number(substr(v_filename,14,8)) ||' ', p_level => 5) ;  

    -- insert into filesystem
    p_write_blob_to_file(p_name=>v_name);


   EXCEPTION
    WHEN OTHERS THEN
              raise;
end;

此处的重要部分是代码p_write_blob_to_file。这是该过程的代码,同时考虑到在我的情况下p_dir采用默认值。

CREATE OR REPLACE procedure p_write_blob_to_file (p_name IN VARCHAR2, p_dir IN VARCHAR2 default 'your_directory' )
   IS
      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       varchar2(2000);
      v_mime_type       varchar2(2000);     
   BEGIN
     
    -- Retrieve the BLOB for reading
    SELECT blob_content, filename, mime_type 
      INTO l_blob, l_file_name, v_mime_type
      FROM apex_application_temp_files
    WHERE name = p_name;
    
      -- 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.

      l_out_file :=
         UTL_FILE.fopen (p_dir,
                         l_file_name,
                         'wb',
                         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;
/

下载文件

要下载文件,您需要相反的路径。

  • 按钮或链接下载必须与组件PL / SQL关联
  • 该按钮首先将文件从服务器目录加载到列中
  • 该按钮然后下载文件

我打算在这里编写所有命令,但是您在这两个动作中都找到了一个很好的例子:

  • 将文件从目录加载到列

https://renaps.com/en/blog/how-to/how-to-load-file-content-to-a-blob-field-and-unload-blob-content-to-a-file-on-the-os

  • 下载文件

https://oracle-base.com/articles/misc/apex-tips-file-download-from-a-button-or-link#apex-button

尝试尝试一下,让我知道您可能会发现的任何问题。唯一棘手的事情是,在Apex中,您需要传递要下载的文件的名称。因此,用户必须确切知道服务器中的名称。您不能做的是为服务器提供图形界面,以便选择文件。