使用PL / SQL

时间:2016-12-30 09:56:21

标签: oracle plsql

created a Concurrent Program使用PL / SQL从长参数化查询创建Excel文件。 程序成功完成后,文件将放在远程服务器的目录中,大小通常约为4 MB。 我正在考虑一种方法来通知请求者并使他/她能够将文件保存到他们的本地目录。 但是,由于32 Kilobyte限制,我无法使用UTL_MAIL通过电子邮件附加和发送文件。 (Does UTL_MAIL have an attachment limit of 32k)。

在同一篇文章中,Tom Kyte首选的方法是:

  1. 将附件存储到数据库中。
  2. 通过电子邮件发送一封带有链接的电子邮件。链接指向我的数据库 - 使用URL。
  3. 有了这个,我正在考虑采用相同的方法,并使用下面的块通知请求者并使他/她能够下载所述Excel文件:

    declare
    
        l_url_link  varchar2(100);  -- how can i get the URL of the File?
    
    BEGIN 
    
        UTL_MAIL.SEND(sender     => 'xxx@oracle.com'
                    , recipients => 'Migs.Isip.23@Gmail.com'
                    , subject    => 'Testmail'
                    , message    => 'Your File is Ready to be downloaded, click the link here: '||l_url_link);
    
    END;
    

    我的问题是:

    1. 如何生成"网址"使用PL / SQL的远程文件?
    2. 是否需要授予用户访问远程服务器的权限以下载文件?
    3. 谢谢!

      Oracle数据库版本:

      Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
      PL/SQL Release 11.2.0.4.0 - Production
      "CORE   11.2.0.4.0  Production"
      TNS for Solaris: Version 11.2.0.4.0 - Production
      NLSRTL Version 11.2.0.4.0 - Production
      

2 个答案:

答案 0 :(得分:0)

这是我编写的pl / sql函数,用于检索并发日志文件或输出文件的URL。如果您将Excel文件写入并发输出,这应该可以正常工作。让我知道你是怎么办的。我没有检查是否会给出正确的mime类型或扩展名 - 不确定EBS如何处理这个,但函数本身肯定会按照12.1.3进行编译。

规格

FUNCTION  get_concurrent_url (p_file_type   IN  VARCHAR2
                             ,p_request_id  IN  NUMBER
                             ,p_expiry      IN  NUMBER)
RETURN VARCHAR2;

/*  Get a URL to view the log/output
    File Type is LOG or OUT 
    Request ID is the concurrent request ID
    Expiry is in minutes                                                */
FUNCTION  get_concurrent_url (p_file_type   IN  VARCHAR2
                             ,p_request_id  IN  NUMBER
                             ,p_expiry      IN  NUMBER)
RETURN VARCHAR2                             
IS 

CURSOR c_gwyuid
IS
    SELECT  profile_option_value
    FROM    fnd_profile_options         FPO
           ,fnd_profile_option_values   FPOV
    WHERE   FPO.profile_option_name     =   'GWYUID'
    AND     FPO.application_id          =   FPOV.application_id
    AND     FPO.profile_option_id       =   FPOV.profile_option_id; 

CURSOR c_two_task     
IS
    SELECT  profile_option_value
    FROM    fnd_profile_options         FPO
           ,fnd_profile_option_values   FPOV
    WHERE   FPO.profile_option_name     =   'TWO_TASK'
    AND     FPO.application_id          =   FPOV.application_id
    AND     FPO.profile_option_id       =   FPOV.profile_option_id;

l_request_id        NUMBER;
l_file_type         VARCHAR2 (3 BYTE);
l_expiry            NUMBER;
l_two_task          VARCHAR2 (100 BYTE);
l_gwyuid            VARCHAR2 (100 BYTE);
l_url               VARCHAR2 (1024 BYTE); 

BEGIN

l_request_id    :=  p_request_id;
l_file_type     :=  p_file_type;
l_expiry        :=  p_expiry;

FOR i IN c_gwyuid LOOP
    l_gwyuid := i.profile_option_value;
END LOOP;

FOR i IN c_two_task LOOP
    l_two_task := i.profile_option_value;
END LOOP;        

IF l_file_type = 'LOG' THEN  
    l_url := fnd_webfile.get_url
                (file_type      =>  fnd_webfile.request_log
                ,id             =>  l_request_id
                ,gwyuid         =>  l_gwyuid
                ,two_task       =>  l_two_task
                ,expire_time    =>  l_expiry);
ELSE 
    l_url := fnd_webfile.get_url
                (file_type      =>  fnd_webfile.request_out
                ,id             =>  l_request_id
                ,gwyuid         =>  l_gwyuid
                ,two_task       =>  l_two_task
                ,expire_time    =>  l_expiry);
END IF;

RETURN l_url;

END get_concurrent_url;

答案 1 :(得分:0)

我能够使用Oracle EBS中的FND_GFM文件上传器包使用(稍有不同)方法找到解决方案。 FND_GFM是在从前端应用程序页面上传文件时通常在Oracle EBS中使用的包。

首先,使用上一篇文章中的代码生成Excel文件(xlsx):Create an Excel File (.xlsx) using PL/SQL

然后将文件插入FND_LOBS并从操作系统中删除(为了便于管理),最后使用UTL_FILE作为电子邮件发送:

procedure generate_and_send_excel
is

    l_content   varchar2(250);
    l_file_url  varchar2(4000);  
    l_directory varchar2(250);
    l_filename  varchar2(250);
    l_message   clob;
    l_instance   varchar2(100);
    l_ebs_url    varchar2(100);

begin

    /* your excel generation code here */

    l_content   := 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
    l_directory := 'EXT_TAB_DATA';
    l_filename  := 'report.xlsx';

    select  instance_name
    into    l_instance
    from    v$instance;

    select  home_url
    into    l_ebs_url
    from    icx_parameters;

    IMPORT_TO_LOB (p_file_name    => l_filename          -- this is the actual filename of the saved OS File
                 , p_directory    => l_directory         -- should be a defined directory in the Database
                 , p_content_type => l_content           -- standard for Excel Files
                 , p_program_name => 'your prog here'
                 , p_program_tag  => 'your prog here'
                 , p_file_url     => l_file_url);        -- this will be the generated URL of your File

    utl_file.fremove(l_directory, l_filename);

    l_message := l_message||'<h2 style="color: #5e9ca0;">'||l_title||'</h2>';
    l_message := l_message||'<h3 style="color: #2e6c80;">Report is Ready for Download: <a href="'||l_file_url||'">'||l_filename||'</a></h3>';
    l_message := l_message||'<p>File was generated on '|| sysdate ||' from <a href="'||l_ebs_url||'">'||l_instance||'</a></p>';
    l_message := l_message||'<strong>Regards,</strong><br/><strong>Sample Team</strong>';
    l_message := l_message||'<br/><a href="mailto:ERPSupport@alorica.com">Sample@sample.com</a>';


    UTL_MAIL.SEND(sender     => 'SAMPLE@SAMPLE.com'
                , recipients => 'Migs.Isip.23@gmail.com'
                , subject    => 'Hello message'
                , message    => l_message
                , mime_type  => 'text/html; charset=us-ascii');

end generate_and_send_excel;

以下过程插入FND_LOBS(没有可用的种子API):

Procedure IMPORT_TO_LOB (p_file_name    IN  FND_LOBS.FILE_NAME%TYPE
                       , p_directory    IN  dba_directories.directory_name%type  
                       , p_content_type IN  FND_LOBS.file_content_type%type
                       , p_program_name IN  FND_LOBS.program_name%type
                       , p_program_tag  IN  FND_LOBS.program_tag%type
                       , p_language     IN  FND_LOBS.language%type      default 'US'
                       , p_file_format  IN  FND_LOBS.file_format%type   default 'binary'
                       , p_file_url     OUT varchar2)
IS
    PRAGMA AUTONOMOUS_TRANSACTION;
    lBlob               BLOB;
    lFile               BFILE := BFILENAME(p_directory, p_file_name);
    L_ORA_CHARSET       VARCHAR2(100);
    P_COUNT             NUMBER;

BEGIN

    SELECT  value 
    into    l_ora_charset
    FROM    nls_database_parameters
    where   parameter = 'NLS_CHARACTERSET';

    insert into FND_LOBS 
    (
        file_id
    ,   file_name
    ,   file_content_type
    ,   file_data
    ,   upload_date
    ,   expiration_date
    ,   program_name
    ,   program_tag
    ,   LANGUAGE
    ,   oracle_charset
    ,   file_format
    )
    values
    (
        fnd_lobs_s.NEXTVAL        -- FILE_ID
    ,   p_file_name               -- FILE_NAME
    ,   p_content_type            -- FILE_CONTENT_TYPE
    ,   EMPTY_BLOB()              -- FILE_DATA
    ,   sysdate                   -- UPLOAD_DATE
    ,   NULL                      -- EXPIRATION_DATE
    ,   p_program_name            -- PROGRAM_NAME
    ,   p_program_tag             -- PROGRAM_TAG
    ,   p_language                -- LANGUAGE
    ,   l_ora_charset             -- ORACLE_CHARSET
    ,   p_file_format             -- FILE_FORMAT   
    )
    RETURNING file_data INTO lBlob;

    DBMS_LOB.OPEN(lFile, DBMS_LOB.LOB_READONLY);
    DBMS_LOB.OPEN(lBlob, DBMS_LOB.LOB_READWRITE);
    DBMS_LOB.LOADFROMFILE(DEST_LOB => lBlob,
                          SRC_LOB  => lFile,
                          AMOUNT   => DBMS_LOB.GETLENGTH(lFile));                              
    DBMS_LOB.CLOSE(lFile);
    DBMS_LOB.CLOSE(lBlob);        

    commit;

    p_file_url := fnd_gfm.construct_download_url (fnd_web_config.gfm_agent, fnd_lobs_s.currval);

END IMPORT_TO_LOB;

请注意,这是AUTONOMOUS_TRANSACTION,因此需要在返回调用包/块之前提交。

希望有帮助!