2016-12-30 6 views
2

PL/SQLを使用して長い、パラメータ化クエリからExcelファイルを作成し、I created a Concurrent Programを使用してリモートファイルのURLを生成します。 プログラムが正常に完了すると、ファイルはリモートサーバーのディレクトリに置かれ、通常はサイズが約4 MBです。 私はリクエスタに通知し、ローカルディレクトリにファイルを保存する方法を考えています。 しかし、私はUTL_MAILを使用して、ファイルを添付して送信することはできません。その理由は、32キロバイトの制限のためです。 (Does UTL_MAIL have an attachment limit of 32k)。同じポストでは、PL/SQL

、トムKyteの好ましいアプローチは、になるであろう:

  1. ストアデータベースへの付着。
  2. 電子メールにはリンク付きの非常に小さなメールがあります。リンクは私のデータベースを指しています - URLを使用しています。それと

、私は同じアプローチを取って、要求者に通知したExcelファイルをダウンロードするために彼/彼女を有効にするには、以下のブロックを使用して考えていた:

declare 

    l_url_link varchar2(100); -- how can i get the URL of the File? 

BEGIN 

    UTL_MAIL.SEND(sender  => '[email protected]' 
       , recipients => '[email protected]' 
       , subject => 'Testmail' 
       , message => 'Your File is Ready to be downloaded, click the link here: '||l_url_link); 

END; 

私の質問は次のようになります。

  1. は、どのように私はPL/SQLを使用してリモートファイルの「URL」を生成することができますか?
  2. ファイルをダウンロードするには、リモートサーバーへのアクセスをユーザーに許可する必要がありますか?

ありがとうございました!

のOracle Databaseバージョン:

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

[フォローアップを確認しましたか?](https://asktom.oracle.com/pls/asktom/f?p=100:11:0:::P11_QUESTION_ID:4942282003467688992015399200346169843)ファイルをファイルシステムのディレクトリに書き込むのではなく、FTPサーバー、Webサーバー、またはミドルウェアを使用することができます(既存のインフラストラクチャーについてはわかりません) 、またはあなたが追加できるもの、あるいはあなたが公開できるもの。 –

+0

こんにちは@AlexPoole、はい私はそれを見ましたが、私はそれをかなり理解していませんでした。明確化のためにありがとう。ファイルをアプリケーションサーバーに書き込んでいます。ファイルがApp Serverからのものだった場合、アプローチを提案できますか?ありがとうございました! –

+0

私はこれに対する答えを持っていますが、あなたの並行プログラムがどのように実行されているかを確認したいと思います - あなたはe-business suiteを実行していますか? –

答えて

0

私は、Oracle EBSにFND_GFMファイルアップローダパッケージを使用して(わずかに異なる)メソッドを使用して、このための解決策を見つけることができました。 FND_GFMは、フロントエンド・アプリケーション・ページからファイルをアップロードするときにOracle EBSで通常使用されるパッケージです。

まず、Excelファイル(XLSX)以前の記事からコード使用して生成する:Create an Excel File (.xlsx) using PL/SQL

は次にファイルFND_LOBSに挿入され、OSから除去(良好なハウスキーピングのために)、そして最後として送信されますUTL_FILEを使用して電子メール:FND_LOBSに挿入するには、以下の

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:[email protected]ica.com">[email protected]</a>'; 


    UTL_MAIL.SEND(sender  => '[email protected]' 
       , recipients => '[email protected]' 
       , subject => 'Hello message' 
       , message => l_message 
       , mime_type => 'text/html; charset=us-ascii'); 

end generate_and_send_excel; 

手順(使用可能なシードの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なので、呼び出し元のパッケージ/ブロックに戻る前にコミットする必要があることに注意してください。

希望すること!

0

ここでは、私は、同時ログファイルまたは出力ファイルのいずれかのURLを取得するために書いたPL/SQLファンクションです。 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; 
+0

残念ながら、ファイルは出力として書き込まれていません。バイナリの 'xlsx'ファイルとしてOSに書き込まれます。しかし、私はこれを便利にしておきます。ありがとう! –