2010-07-22 87 views
1

我想生成有關最磁盤讀取查詢報告。生成的報告將作爲電子郵件發送。我寫了一些代碼如下。 當我包括前15名查詢它工作正常,但如果我增加hte計數我得到'數值或價值錯誤'。我想這是因爲我超過一些數據類型限制 ,但無法識別它。任何人都看到了這個問題?我如何發送巨大的報告,而沒有像這樣的錯誤?ORACLE數字或值錯誤

我有一個F_GENERATE_REPORT功能和P_SEND_REPORT_AS_EMAIL程序。 P_SEND_REPORT_AS_EMAIL過程使用F_GENERATE_REPORT作爲身體等UTL_MAIL.SEND電子郵件的 (消息=> F_GENERATE_REPORT(5)),其中5用於頂部5.

錯誤occures上在程序P_SEND_REPORT_AS_EMAIL線UTL_MAIL.SEND()

感謝所有。

clgenerated_html_markup是CLOB。

FOR cur_for_query IN (SELECT * 
         FROM (SELECT buffer_gets,rows_processed,executions, 
            fetches,hash_value,sql_text, disk_reads, 
            rank() over(ORDER BY disk_reads DESC) AS rank FROM v$sqlarea) 
         WHERE rank <= nquery_count) 
LOOP 
    --dbms_output.put_line(counter); 
    --counter := counter + 1; 
    clgenerated_html_markup := clgenerated_html_markup || HTF.TABLEROWOPEN || CHR(10) ; 
    clgenerated_html_markup := clgenerated_html_markup || HTF.TABLEDATA(cur_for_query.rank,null,null,null,null,null,'class=tdData') || CHR(10) ; 
    clgenerated_html_markup := clgenerated_html_markup || HTF.TABLEDATA(cur_for_query.sql_text,null,null,null,null,null,'class=tdSQLText') || CHR(10) ; 
    clgenerated_html_markup := clgenerated_html_markup || HTF.TABLEDATA(TO_CHAR(NVL(cur_for_query.disk_reads,'')),'CENTER',null,null,null,null,'class=tdData') || CHR(10) ; 
    clgenerated_html_markup := clgenerated_html_markup || HTF.TABLEDATA(TO_CHAR(NVL(cur_for_query.buffer_gets,'')),'CENTER',null,null,null,null,'class=tdData') || CHR(10) ; 
    clgenerated_html_markup := clgenerated_html_markup || HTF.TABLEDATA(TO_CHAR(NVL(cur_for_query.executions,'')),'CENTER',null,null,null,null,'class=tdData') || CHR(10) ; 
    clgenerated_html_markup := clgenerated_html_markup || HTF.TABLEDATA(TO_CHAR(NVL(cur_for_query.fetches,'')),'CENTER',null,null,null,null,'class=tdData') || CHR(10) ; 
    --clgenerated_html_markup := clgenerated_html_markup || HTF.TABLEDATA('','CENTER',null,null,null,null,'class=tdData') || CHR(10) ; 
    --clgenerated_html_markup := clgenerated_html_markup || HTF.TABLEDATA('','CENTER',null,null,null,null,'class=tdData') || CHR(10) ; 
    clgenerated_html_markup := clgenerated_html_markup || HTF.TABLEROWCLOSE || CHR(10) ; 
END LOOP; 

發送電子郵件程序

PROCEDURE P_SEND_REPORT_AS_EMAIL 
(
vreceipent VARCHAR2, 
vsubject VARCHAR2, 
nquery_count NUMBER DEFAULT 5 
) 

IS 
BEGIN 

-- INPUT VALIDATION 
IF vreceipent IS NULL THEN 
      RAISE_APPLICATION_ERROR(value_can_not_be_null,'DBA_EXHAUSTIVE_QUERY_PKG::P_SEND_REPORT_AS_EMAIL::Receipent Email Address Can Not Be Null.'); 
END IF; 
-- END OF INPUT VALIDATION 


UTL_MAIL.SEND(sender => 'mehmet.altipa[email protected]', 
       recipients => vreceipent, 
       subject => NVL(vsubject,''), 
       message => F_GENERATE_REPORT(nquery_count), 
       mime_type => 'text/html; charset=us-ascii'); 

EXCEPTION 
WHEN OTHERS THEN 
    -- TODO LOG ERROR HERE 
RAISE; 

END P_SEND_REPORT_AS_EMAIL; 

回答

5

爲UTL_MAIL.SEND的簽名是:

UTL_MAIL.SEND (
    sender  IN VARCHAR2 CHARACTER SET ANY_CS, 
    recipients IN VARCHAR2 CHARACTER SET ANY_CS, 
    cc   IN VARCHAR2 CHARACTER SET ANY_CS DEFAULT NULL, 
    bcc   IN VARCHAR2 CHARACTER SET ANY_CS DEFAULT NULL, 
    subject  IN VARCHAR2 CHARACTER SET ANY_CS DEFAULT NULL, 
** message  IN VARCHAR2 CHARACTER SET ANY_CS, ** 
    mime_type IN VARCHAR2 DEFAULT 'text/plain; charset=us-ascii', 
    priority IN PLS_INTEGER DEFAULT NULL); 

正如你可以看到你用CLOB調用此方法與參數message代替VARCHAR2。隱含的轉換最多可達32k字節,一切都很好。我懷疑你得到的錯誤是當你試圖用一個不能轉換成VARCHAR2(> 32k字節)的CLOB提供過程時。

在Oracle中發送帶CLOB消息的電子郵件的最簡單方法是通過APEX_EMAIL(在最新版本的數據庫上默認安裝,如果未安裝,您可以從Oracle下載APEX)。在舊版本中,您需要一些解決方法。例如,Tom Kyte介紹瞭如何在AskTom上使用use java to send large emails in Oracle 8i。或者,您也可以編寫自己的PLSQL過程或在網上進行一些研究,您會發現可以使用UTL_TCP與郵件服務器交談(並以您選擇的格式發送數據)。

+0

+1 APEX_Email看起來不錯。如果在我們使用utl_smpt包裝器時可用,會節省大量時間。 – 2010-07-22 14:39:25

3

一個VARCHAR2的PL/SQL的最大大小爲32K。因爲clgenerated_html_markup使用的是clob,所以你很好,但是當你調用UTL_MAIL.SEND時,它試圖將它轉換爲Varchar2,而不能。您必須切換到較低級別的電子郵件工具,例如UT38_SMTP,如here

在鏈路看多,我不知道這是最好的例子,但我還沒有找到接受CLOB作爲發出使用UTL_SMTP的消息的過程的一個很好的例子。這個概念是相似的,但你的頭看起來應該更像是這樣的:

PROCEDURE SendSMTP(
     pTo  Varchar2 Default null, 
     pSubject Varchar2 Default null, 
     pBody  Clob  Default empty_clob, 
     pFrom  Varchar2 Default null, 
     pCC  Varchar2 Default null, 
     pBCC  Varchar2 Default null, 
     pMimeType Varchar2 Default cDefaultMimeType, 
     pSMTPHost Varchar2 Default cDefaultMailServer, 
     pSMTPPort pls_integer Default cDefaultPort) 

Psoug.org有語法here一個很好的參考。

相關問題