PL/SQL - 防止 ORA-06502

Posted

技术标签:

【中文标题】PL/SQL - 防止 ORA-06502【英文标题】:PL/SQL - prevent ORA-06502 【发布时间】:2011-11-04 14:00:23 【问题描述】:

我经常收到这个错误(太烦人了!):

错误报告:ORA-06502:PL/SQL:数字或值错误:字符 字符串缓冲区太小 ORA-06512: 在第 305 行 06502. 00000 - "PL/SQL: 数值或数值错误%s"

示例存储过程循环遍历游标(大约有 10k 行),执行一些逻辑,然后使用 dbms_output.put_line 将每条记录打印到 Oracle SQL Developer 中的 'Script Output' 选项卡。

有没有办法清除缓冲区或防止出现此错误(并中止 proc 的其余部分)?

如果可能的话,我可以使用Mod function 每处理 10 行左右清除一次缓冲区。

【问题讨论】:

【参考方案1】:

我不相信这个错误与其他答案所暗示的 DBMS_OUTPUT 缓冲区大小有任何关系。如果你溢出那个缓冲区,你得到的错误应该是“ORA-20000: ORU-10027: buffer overflow, limit of ##### bytes”。

此错误通常意味着 PL/SQL 字符串变量太小而无法容纳分配给它的某些值。如果您传递的值大于它可以处理的值,这可能是 DBMS_OUTPUT 内部的。但是您的堆栈跟踪现在确实在堆栈中显示 DBMS_OUTPUT,所以我认为情况并非如此。该错误似乎发生在您的程序的第 305 行。它有什么作用?如果是赋值,那么变量 begin 赋值可能需要声明更大的尺寸。

【讨论】:

啊,好像是这样。在第 305 行有一个赋值,因为我做了:“SQL_STRING := SQL_STRING||”。我将 SQL_STRING 设置为 VARCHAR2(4000),但现在已将其移至 VARCHAR2(32767)。有没有办法克服这个 32767 字节的限制? @toop -- 这是 VARCHAR2 的最大值。如果您需要更大,那么您可以使用 VARCHAR2 的数组(即 PL/SQL 表),在这种情况下,您必须编写将长字符串拆分为多个子字符串的逻辑,或者使用 CLOB,其中case 一些正常的函数必须用对 DBMS_LOB 函数的调用来替换。【参考方案2】:

DBMS_OUTPUT 的默认缓冲区大小为 20000 个字符。你可以用:

DBMS_OUTPUT.ENABLE(1000000);

没有“刷新”的概念,因为在存储过程返回之前没有要刷新的内容。它实际工作的方式是这些行进入数据库中的缓冲区,然后在 SP 完成时由客户端(例如 SQL*Plus)显式获取(使用DBMS_OUTPUT.GET_LINES)该缓冲区。它与您在 C 中可能习惯的 printf() 完全不同。

【讨论】:

如果我的 proc 使用了子块怎么办> 我不明白你的意思? BEGIN 中的 BEGIN 是否会被视为一个单独的过程来返回输出? 不,缓冲区是在会话级别分配的。 但该错误与 DBMS_OUTPUT 缓冲区无关。如果你溢出那个缓冲区,你会得到ORA-20000: ORU-10027: buffer overflow, limit of #### bytes【参考方案3】:

要输出大量内容,最好使用 UTL_FILE 而不是 DBMS_OUTPUT 并检查文件。或者使用临时表并在自治过程中进行插入,这样即使主过程出于任何原因必须进行回滚,您也可以看到结果。 在这两种情况下,您都可以在程序仍在运行时看到部分结果。这是 DBMS_OUTPUT 无法提供的。

【讨论】:

【参考方案4】:

将值作为 CLOB 而不是 varchar 接收

【讨论】:

以上是关于PL/SQL - 防止 ORA-06502的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQL: 数字或值错误 - ORA-06502

出现错误 ORA-06502: PL/SQL: numeric or value error

ORA-06502 PL/SQL:数字或值错误:字符到数字的转换错误;

ORA-06502: PL/SQL: 在空游标的情况下出现数字或值错误

ORA-06502: PL/SQL: 数字或值错误: NULL 索引表键值

ORA - 06502:PL/SQL:数字或值错误:批量绑定:截断绑定