Oracle 使用PL/SQL生成远程文件的URL

Oracle 使用PL/SQL生成远程文件的URL,oracle,plsql,Oracle,Plsql,我使用PL/SQL从一个长的参数化查询创建一个Excel文件。 一旦程序成功完成,该文件将被放置在远程服务器的目录中,通常大小约为4MB。 我正在考虑一种方法,通知请求者并使其能够将文件保存到本地目录。 但是,由于32 KB的限制,我无法使用UTL_MAIL通过电子邮件附加和发送文件。() 在同一篇文章中,Tom Kyte更喜欢的方法是: 将附件存储到数据库 用链接发送一封非常小的电子邮件。链接指向我的数据库-使用URL 因此,我考虑采用相同的方法,使用下面的块通知请求者,并使其能够下载所述Ex

我使用PL/SQL从一个长的参数化查询创建一个Excel文件。 一旦程序成功完成,该文件将被放置在远程服务器的目录中,通常大小约为4MB。 我正在考虑一种方法,通知请求者并使其能够将文件保存到本地目录。 但是,由于32 KB的限制,我无法使用
UTL_MAIL
通过电子邮件附加和发送文件。()

在同一篇文章中,Tom Kyte更喜欢的方法是:

  • 将附件存储到数据库
  • 用链接发送一封非常小的电子邮件。链接指向我的数据库-使用URL
  • 因此,我考虑采用相同的方法,使用下面的块通知请求者,并使其能够下载所述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;
    
    我的问题是:

  • 如何使用PL/SQL生成远程文件的“URL”
  • 是否需要授予用户访问远程服务器的权限才能下载文件
  • 谢谢大家!

    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
    

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

    规格

    身体


    我使用Oracle EBS中的
    FND_GFM
    文件上传程序包,通过一种(稍微不同的)方法找到了解决方案。
    FND_GFM
    是Oracle EBS从前端应用程序页面上载文件时通常使用的软件包

    首先,使用上一篇文章中的代码生成Excel文件(xlsx):

    然后将该文件插入到
    FND_LOBS
    中,并从操作系统中删除(为了更好地管理),最后使用
    UTL_文件作为电子邮件发送:

    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;
    
    请注意,这是一个请求,因此需要在返回到调用包/块之前提交它


    希望有帮助

    如果要将文件写入文件系统目录,而不是将其存储在数据库中(作为CLOB/BLOB?),则可以使用FTP服务器、web服务器或中间件。。。我们不知道你现有的基础设施,或者你可以添加什么,或者你可以公开什么。嗨@AlexPoole,是的,我看到了,但我不太明白。谢谢你的澄清。我正在将文件写入应用程序服务器。如果文件来自应用程序服务器,您能建议一种方法吗?非常感谢。我对此有一个答案,但希望您确认您的并行程序是如何运行的-您正在运行电子商务套件吗?您好@PeteMahon,是的,EBS 12.1.3,我目前正在尝试将其插入
    FND_LOBS
    中,然后使用
    FND_GFM
    包生成URL。请告诉我你对此的建议。谢谢不幸的是,该文件没有作为输出写入。它作为二进制
    xlsx
    文件写入操作系统。但我会把这个放在手边。谢谢
    /*  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;
    
    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;
    
    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;