难以找到数字或值错误

时间:2014-11-10 07:16:58

标签: plsql oracle9i

由于不明原因,我收到以下错误,您介意看看我的代码并找到问题吗?

  

ORA-06502:PL / SQL:数字或值错误ORA-06512:at   “PENTACMS.BPC_SEND_CUST_OBJ_CHOUT_EMAIL”,第141行ORA-06512:在线   2

第141行如下:

LINE141:        lv_table := lv_table || lv_temp;

此代码工作正常一次甚至电子邮件正在发送,但在第二轮它将停止以上错误。 我在下面调用函数如下:

begin
 BPC_SEND_CUST_OBJ_CHOUT_EMAIL;
end;
  
procedure BPC_SEND_CUST_OBJ_CHOUT_EMAIL AS
    l_html VARCHAR2(200);   
    ln_indx number;

    Cursor CR_CUST_CH_OBJ IS
            select 
            V_REQUESTOR col1,
            V_SOURCE_NAME col2,
            (select distinct V_DESC from AAAA_OBJECT_TYPE xx where xx.V_TYPE = a.V_TYPE and xx.v_status = 'A') col3,
            V_CUST_NAME col4,
            V_CUST_REF_NO col5,
            D_REQUEST col6,
            D_request + v_duration col7,
            round(sysdate - (D_request + v_duration))||' days'  col8 ,
            (select V_EMAIL_ID from AAAA_CUST_USERS  where V_USER_NAME = V_REQUESTOR   ) col9,
            '' col10,
            (select V_STATUS from AAAA_CUST_USERS  where V_USER_NAME = V_REQUESTOR   ) col11
    from    AAAA_SOURCE_TRACK a, AAAA_CUSTOMER b
    where
            D_REQUEST > to_date('01/01/2010','DD/MM/YYYY')
            and a.V_CUST_CODE =   b.V_CUST_CODE
            and V_REFERENCE is not null
            and D_RECEIVED is Null
            and D_APPROVED is null
            and a.V_STATUS ='CHECKOUT'  --and b.v_status = 'A'
            and a.D_request + a.v_duration < sysdate
    order by V_CUST_NAME,V_REQUESTOR;                                                                   


    to_array  array_a := array_a();
    cc_array  array_a := array_a();
    v_date varchar2(200);
    v_subject varchar2(400);
    D_DATE DATE;     

    lv_title varchar2(400);
    lv_body_msg varchar2(1000);
    lv_table varchar2(10000);
    lv_cust_name varchar2(150);
    ln_index number;  
    lv_email_txt varchar2(32767); 
    lv_fake_emailLst varchar2(2000);
    lv_temp varchar2(1000);

BEGIN
    ln_index := 0; 

    lv_table := '';

    D_DATE := add_months(sysdate,-1);--TO_DATE('01-04-2014','DD-MM-YYYY');
    v_date :=  TO_CHAR(D_DATE,'YYYY-MM');
    v_subject := 'subject text from '||to_char(add_months(sysdate,'-12'),'MONTHYYYY') ||' to '|| to_char(sysdate, 'MONTHYYYY') ;

    to_array.extend(1);
    to_array(1):='aaaa@bbbb.com';



    l_html := '<html> <head> <title>Title</title>   </head>  <body style="font:''Segoe UI''; font-size:14px">'; 

    lv_body_msg := '<p>msg1 <br />';
    lv_body_msg := lv_body_msg ||'msg2<br />';
    lv_body_msg := lv_body_msg ||'msg3<br />';

    lv_table := '<table border="1"  cellpadding="0" style="font:''Segoe UI''; font-size:12px"><b>
                    <TR align="center"><TH colspan="9" bgcolor="#FF0000" style="color:white" scope="col">List of objects locked</TH></TR>
                    <TR align="center" bgcolor="#FFFF00" >
                        <TD>Requestor</TD>
                        <TD>Source Name</TD>
                        <TD>Type</TD>
                        <TD>Customer  Name</TD>
                        <TD>Customer Ref No</TD>
                        <TD>Request date</TD>
                        <TD>Date of return object</TD>
                        <TD>Delay</TD>
                        <TD>Requestor Remark</TD>
                    </TR>
                    </b>';            

    lv_title := 'Dear ';

    FOR RI IN CR_CUST_CH_OBJ
    LOOP  
        IF ln_index = 0 THEN
              lv_cust_name := RI.col4;
        END IF;

        IF lv_cust_name != RI.col4 THEN   

            lv_email_txt := l_html ||lv_fake_emailLst||'<br /><br />'|| lv_title||'<br /><br />'|| lv_body_msg ||lv_table ||  '</table><br/><br/>' ;
            lv_email_txt := lv_email_txt || '<p style="color:red; font-style:italic"> ** This email is auto generated by FMS server. ('||sysdate||')</p>';
            lv_email_txt:= lv_email_txt || '</body>  </html>';  

            BPC_HTML_EMAIL( p_from      => 'cccc@bbbb.com',
                            p_subject   => v_subject || lv_cust_name,
                            p_text_msg  => 'This email is in HTML format. Please enable HTML format.',
                            p_html_msg  => lv_email_txt,
                            p_smtp_host => '100.10.10.201',
                            p_to_recipients => to_array,
                            p_cc_recipients => cc_array);

            lv_cust_name := RI.col4;   

                lv_table := '<table border="1"  cellpadding="0" style="font:''Segoe UI''; font-size:12px"><b>
                <tr align="center"><th colspan="9" bgcolor="#FF0000" style="color:white" scope="col">List of objects locked</th></tr>
                <TR align="center" bgcolor="#FFFF00" >
                    <TD>Requestor</TD>
                    <TD>Source Name</TD>
                    <TD>Type</TD>
                    <TD>Customer  Name</TD>
                    <TD>Customer Ref No</TD>
                    <TD>Request date</TD>
                    <TD>Date of return object</TD>
                    <TD>Delay</TD>
                    <TD>Requestor Remark</TD>
                </TR>
                </b>';            

                lv_title := 'Dear ';            
        END IF ;       


        lv_temp := '<TR><TD>'||RI.col1||'</TD>
                            <TD>'||RI.col2||'</TD>
                            <TD>'||RI.col3||'</TD>
                            <TD>'||RI.col4||'</TD>
                            <TD>'||RI.col5||'</TD>
                            <TD>'||RI.col6||'</TD>
                            <TD>'||RI.col7||'</TD>
                            <TD>'||RI.col8||'</TD>
                            <TD>'||RI.col10||'</TD>
                    </TR>';   
LINE141:        lv_table := lv_table || lv_temp;                                  
        --dbms_output.put_line(lv_temp) ;
        --to_array.extend(1);
        --to_array(ln_indx) := RI.col9;    
        ln_index := ln_index + 1;

        IF(INSTR(lv_title ,RI.col1) =0) THEN
            lv_title := lv_title || RI.col1 ||', ';
            lv_fake_emailLst := lv_fake_emailLst || RI.col9 ||',';

        END IF;
    END LOOP;

END;

1 个答案:

答案 0 :(得分:1)

VARCHAR2变量太短。通常你应该得到这样的东西

ORA-06502: PL/SQL: numeric or value error: character string buffer too small

以下内容再现了行为

declare
  l_string varchar2(10000);
begin
  for i in 1..10001 loop
    l_string := l_string || 'x';
  end loop;
end;

输出

declare
  l_string varchar2(10000);
begin
  for i in 1..10001 loop
    l_string := l_string || 'x';
  end loop;
end;
Error at line 1
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at line 5

您可以按照user272735的建议使用CLOB,也可以将lv_table增加到更大的值。但是你应该在它发生之前检查溢出。粗略喜欢这个

if coalesce(length(lv_table),0)+coalesce(length(lv_temp),0) <= 10000 then
  lv_table := lv_table || lv_temp;   
else
  ... do something else here that won't lead to a crash
end if;