Oracle 存储过程无法生成 csv 文件 - ORA-06502: PL/SQL: numeric or value error: string buff

Posted

技术标签:

【中文标题】Oracle 存储过程无法生成 csv 文件 - ORA-06502: PL/SQL: numeric or value error: string buff【英文标题】:Oracle stored procedure fails to generate csv file - ORA-06502: PL/SQL: numeric or value error: character string buff 【发布时间】:2021-09-18 21:16:39 【问题描述】:

我有一个从表中读取值并生成 csv 文件并将它们邮寄的过程。在我在 DB 中输入新条目之前,该过程运行良好,之后无法生成 CSV 文件。程序抛出异常“ORA-06502: PL/SQL: numeric or value error: string buff”,我试图打印从表中读取的值以检查它是否正常工作。

通过打印值,我可以看到其中一个新条目没有被正确读取,我相信这可能是问题的原因。

我已经检查了 O Brien 之后的值被打印在新行中的原因,我可以看到该值位于表格中,就像这样,光标在新行上:

在日志中打印的错误:

引发错误:ORA-06512:在“UPDATER.mypro”第 50 行

ORA-06502:PL/SQL:数字或值错误:字符串缓冲区太小

这是我的代码:

create or replace PROCEDURE         mypro AS 

O_ErrorCode  Number;
O_ErrorDesc  VARCHAR2(100);
l_clob2  VARCHAR2 (32767);
l_attach_text2 VARCHAR2 (32767);
l_attach_text_h2 VARCHAR2 (32767);
v_From VARCHAR2(280) := ' abc';
v_Recipient VARCHAR2(280) := 'efggg';
v_Subject VARCHAR2(280) := 'Entry & Details';
v_Mail_Host VARCHAR2(230) := 'abcd';
v_Mail_Conn utl_smtp.Connection;
crlf VARCHAR2(200) := chr(13)||chr(10);
FC_SV_STATUS_DESC VARCHAR2(100) := 'open';



CURSOR c2 IS 
   select FC_CA_RECORD_ID,to_char(FC_CA_INPUT_DATE ,'DD-MM-YY')as FC_CA_INPUT_DATE,FC_CA_PAYER,FC_CA_AMOUNT,FC_CA_TYPE,FC_CA_PAYEE,FC_CA_ADD_REMARKS,FC_CA_COMMENTS,FC_CA_ACC_NO,FC_CA_POLICY_NO,to_char(FC_CA_BRANCHCONF_DATE ,'DD-MM-YY')as FC_CA_BRANCHCONF_DATE,FC_CA_CONFIRMED_BY,to_char(FC_CA_SHEETUPDATE_DATE ,'DD-MM-YY')as FC_CA_SHEETUPDATE_DATE,to_char(FC_CA_MAILUPDATE_DATE ,'DD-MM-YY')as FC_CA_MAILUPDATE_DATE,to_char(FC_CA_UPLOAD_TIME ,'DD-MM-YY')as FC_CA_UPLOAD_TIME,FC_CA_UPLOAD_ID FROM Abcd where  FC_CA_STATUS =1 ;

BEGIN

  
l_attach_text_h2 :=
'ID ,INPUT DATE ,PAYER ,AMOUNT ,TYPE ,PAYEE - SORT CODE & BANK ACCOUNT NO ,ADDITIONAL REMARKS ,COMMENTS ,ACCOUNT NUMBER ,POLICY NUMBER ,DATE OF BRANCH CONFIRMATION ,CONFIRMED BY ,SHEETUPDATE DATE ,MAILUPDATE DATE ,DATE-TIME ,USER ID ,STATUS ';

FOR employee_rec2 in c2

LOOP

l_attach_text2 :=      '"' || 
employee_rec2.FC_CA_RECORD_ID        || '","' ||
employee_rec2.FC_CA_INPUT_DATE       || '","' ||
employee_rec2.FC_CA_PAYER            || '","' ||
employee_rec2.FC_CA_AMOUNT           || '","' ||
employee_rec2.FC_CA_TYPE             || '","' ||
employee_rec2.FC_CA_PAYEE            || '","' ||
employee_rec2.FC_CA_ADD_REMARKS      || '","' ||
employee_rec2.FC_CA_COMMENTS         || '","' ||
employee_rec2.FC_CA_ACC_NO           || '","' ||
employee_rec2.FC_CA_POLICY_NO        || '","' ||
employee_rec2.FC_CA_BRANCHCONF_DATE  || '","' ||
employee_rec2.FC_CA_CONFIRMED_BY     || '","' ||
employee_rec2.FC_CA_SHEETUPDATE_DATE || '","' ||
employee_rec2.FC_CA_MAILUPDATE_DATE  || '","' ||
employee_rec2.FC_CA_UPLOAD_TIME      || '","' ||
employee_rec2.FC_CA_UPLOAD_ID        || '","' ||
FC_SV_STATUS_DESC                    || '"'   ||chr(13);

l_clob2 := l_clob2||chr(10)||l_attach_text2;

END LOOP;

l_clob2 := l_attach_text_h2 ||chr(13)|| l_clob2;

DBMS_OUTPUT.put_line(' entries processing  completed...');

v_Mail_Conn := utl_smtp.Open_Connection(v_Mail_Host, 25);

utl_smtp.Helo(v_Mail_Conn, v_Mail_Host);

utl_smtp.Mail(v_Mail_Conn, v_From);

utl_smtp.Rcpt(v_Mail_Conn, v_Recipient);

utl_smtp.Data(v_Mail_Conn,
'Date: ' || to_char(sysdate, 'Dy, DD Mon YYYY hh24:mi:ss') || crlf ||
'From: ' || v_From || crlf ||
'Subject: '|| v_Subject || crlf ||
'To: ' || v_Recipient || crlf ||

'MIME-Version: 1.0'|| crlf || -- Use MIME mail standard
'Content-Type: multipart/mixed;'|| crlf ||
' boundary="-----SECBOUND"'|| crlf ||
crlf ||

'-------SECBOUND'|| crlf ||
'Content-Type: text/plain;'|| crlf ||
'Content-Transfer_Encoding: 7bit'|| crlf ||
crlf ||
'Please find the following in the attachments :'|| crlf || -- Message body
'Entry details'|| crlf ||
crlf ||

'-------SECBOUND'|| crlf ||
'Content-Type: text/plain;'|| crlf ||
' name="myfile.csv"'|| crlf ||
'Content-Transfer_Encoding: 8bit'|| crlf ||
'Content-Disposition: attachment;'|| crlf ||
' filename="myfile.csv"'|| crlf ||
crlf ||
 l_clob2  || crlf || -- Content of attachment
crlf ||

'-------SECBOUND--' -- End MIME mail
);

utl_smtp.Quit(v_mail_conn);

DBMS_OUTPUT.put_line('mail send  completed...');

EXCEPTION
  WHEN OTHERS THEN
         O_ErrorCode := SQLCODE;
         O_ErrorDesc := SUBSTR(SQLERRM, 1, 64);
     DBMS_OUTPUT.put_line(O_ErrorCode);
     DBMS_OUTPUT.put_line(O_ErrorDesc);
       SYSTEM.intranet_utils.intranet_log_errors
                                   (
                                    'Exception',
                                    SYSTEM.intranet_utils.intranet_get_errmsg
                                   );

        dba_utils.dba_log_batch ( 'Complete', 'Erred');
        system.intranet_utils.INTRANET_LOG_ERRORS('procedure mypro',
        system.intranet_utils.INTRANET_GET_ERRMSG, 'Error in mypro');
END mypro;

谁能告诉我如何在我的代码中解决这个问题以及如何正确打印日志中的错误??

【问题讨论】:

您当前的异常处理程序正在调用一些您尚未共享的代码,大概这是在其他地方记录错误(希望在自主事务中)。我建议您以附加的raise; 语句结束它,以便调用者也可以看到错误。你的意思是l_clob2 不是clob @AndrewSayer .. 我现在可以得到以下错误..... ORA-20000: ORU-10027: 缓冲区溢出,限制为 20000 字节 @AndrewSayer “你的意思是 l_clob2 不是 clob 吗?” .... 你的意思是改变 l_clob2 的类型? . 我的意思是将列命名为 clob 建议您可能打算将其设置为 clob 数据类型,如果您确实更改了它,您还需要更改一些其他变量。 我希望它是 clob 类型的......无论如何我不认为它是否与我的问题有关......目前删除 dbms_output 后​​的错误是 ORA-06502: PL/SQL:数值或数值错误:字符串buff 【参考方案1】:

它之前工作但停止工作的原因很可能是您达到了 dbms_output 的缓冲区值。默认缓冲区大小为 20000(检查 docs),当超过该大小时,将引发错误 ORU-10027。我建议您删除这些调用 - 因此,任何生产代码都不应该调用 dbms_output。

【讨论】:

删除 dbms 输出帮助我找到了确切的问题 ..... 引发的错误:ORA-06512: at "UPDATER.mypro", line 50 - ORA-06502: PL/SQL: numeric or value错误:字符串缓冲区太小 所以你有 2 个错误,但最初只引发了 dbms_output 异常。很高兴你有它的工作。你能接受答案吗?【参考方案2】:

包“utl_smtp”中过程“data”的第二个参数是VARCHAR2类型,因此限制为32767字节。

对于大数据,您必须使用 开放数据 写入数据 关闭数据

阅读文档

【讨论】:

谢谢,但是....它不能解决我的问题...出现错误:ORA-06512:在“UPDATER.mypro”,第 50 行 - ORA-06502:PL/SQL:数字或值错误:字符串缓冲区太小

以上是关于Oracle 存储过程无法生成 csv 文件 - ORA-06502: PL/SQL: numeric or value error: string buff的主要内容,如果未能解决你的问题,请参考以下文章

自动 CSV 文件生成,在 Oracle 10g 中具有不同列数的两个标题级别的标题

使用存储过程把XML文件插入oracle数据库

在python中调用mysql存储过程并将结果写入csv文件

将变量从 Access(前端)传递到 Oracle(后端)存储过程

错误:Postgresql 中的日期/时间字段值超出范围

在 ORacle 10g 中导入 MySql 生成的 csv 大文件