通过 APEX 从数据库服务器下载文件
Downloading files from the database server via APEX
我正在尝试找到一种通过 APEX 从数据库服务器获取文件的方法。我找不到有关此问题的任何文档。
我可以避免使用 plsql 代码吗?
PS:我在数据库所在的不同服务器上的 tomcat 上启动 APEX。
当我们讨论评论时,让我给你举个例子。我给你写了很多东西所以慢慢来...
上传文件
您可以在 Apex 中拥有一个对象,允许用户浏览要上传的文件。最后,用户按下触发操作的按钮。按钮上传提交页面,按钮本身提交后的动作。任何文件上传都会自动存储在 apex_application_temp_files 中(请记住,我删除了很多关于文件格式、大小等的控件)。
首先创建目录
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;
/
下载文件
要下载文件,您需要相反的路径。
- 按钮或 link 下载必须关联到组件 PL/SQL
- 该按钮首先从服务器中的目录加载文件到一个列中
- 然后点击按钮下载文件
我打算在这里写下所有的命令,但是你在这里找到了两个操作的很好的例子:
- 从目录加载文件到列
- 下载文件
https://oracle-base.com/articles/misc/apex-tips-file-download-from-a-button-or-link#apex-button
尝试对此进行试验,如果您发现任何问题,请告诉我。这里唯一棘手的事情是,在 Apex 中,您需要传递要下载的文件的名称。所以用户必须知道名称,与服务器中的名称完全一样。您不能做的是为服务器提供图形界面以便 select 文件。
我正在尝试找到一种通过 APEX 从数据库服务器获取文件的方法。我找不到有关此问题的任何文档。 我可以避免使用 plsql 代码吗?
PS:我在数据库所在的不同服务器上的 tomcat 上启动 APEX。
当我们讨论评论时,让我给你举个例子。我给你写了很多东西所以慢慢来...
上传文件
您可以在 Apex 中拥有一个对象,允许用户浏览要上传的文件。最后,用户按下触发操作的按钮。按钮上传提交页面,按钮本身提交后的动作。任何文件上传都会自动存储在 apex_application_temp_files 中(请记住,我删除了很多关于文件格式、大小等的控件)。
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;
/
下载文件
要下载文件,您需要相反的路径。
- 按钮或 link 下载必须关联到组件 PL/SQL
- 该按钮首先从服务器中的目录加载文件到一个列中
- 然后点击按钮下载文件
我打算在这里写下所有的命令,但是你在这里找到了两个操作的很好的例子:
- 从目录加载文件到列
- 下载文件
https://oracle-base.com/articles/misc/apex-tips-file-download-from-a-button-or-link#apex-button
尝试对此进行试验,如果您发现任何问题,请告诉我。这里唯一棘手的事情是,在 Apex 中,您需要传递要下载的文件的名称。所以用户必须知道名称,与服务器中的名称完全一样。您不能做的是为服务器提供图形界面以便 select 文件。