错误报告 - ORA-06502:PL / SQL:数值或值错误 ORA-06512:第19行 06502. 00000 - " PL / SQL:数字或值错误%s"
如果我评论第23行& 24 I' LL获得输出,而我不同意我在采取CLOB DATATYPE时犯了错误
SET SERVEROUTPUT ON;
declare
v_messageatt CLOB;
attachment_text CLOB;
CURSOR main_cursor IS
SELECT custid, custname, email
from testlei;
main_cursor_var main_cursor%rowtype;
BEGIN
OPEN main_cursor;
LOOP
FETCH main_cursor INTO main_cursor_var;
EXIT WHEN
( main_cursor%notfound );
IF main_cursor%rowcount = 1 THEN
v_messageatt := v_messageatt || '<tr><th>user ID</th><th>USERNAME</th><th>EMAILID</th></tr>';
END IF;
v_messageatt := v_messageatt || '<tr>';
v_messageatt := v_messageatt|| '<td>'|| main_cursor%rowcount|| '</td>';
v_messageatt := v_messageatt || '<td>'||main_cursor_var.custid||'</td>';
v_messageatt := v_messageatt || '<td>'||main_cursor_var.custname||'</td>';
v_messageatt := v_messageatt || '<td>'||main_cursor_var.email||'</td>';
v_messageatt := v_messageatt || '</tr>';
attachment_text := v_messageatt;
END LOOP;
CLOSE main_cursor;
dbms_output.put_line(attachment_text);
END;
/
答案 0 :(得分:2)
虽然您正在处理CLOB
数据类型,但这些连接正在生成literal
s(最大长度为32,767字节),PL/SQL
将不允许在literal
期间超出此最大值连接。
如果TESTLEI
有足够的行,则其中一个连接中V_MESSAGEATT
的长度超过此限制,并且您将获得ORA-06502
。如果您在块的末尾添加如下所示的异常处理程序,则可以看到此操作:
declare
v_messageatt CLOB;
attachment_text CLOB;
...
... rest of block here ...
...
EXCEPTION WHEN OTHERS THEN
DECLARE
V_ATTACH_ERROR_CHAR_COUNT NUMBER;
BEGIN
V_ATTACH_ERROR_CHAR_COUNT := DBMS_LOB.getlength(V_MESSAGEATT);
DBMS_OUTPUT.PUT_LINE('Failed to build the attachment:' || V_ATTACH_ERROR_CHAR_COUNT);
END;
END;
/
当您运行上述内容时,您应该收到如下消息,其数字刚好超过32767
:
Failed to build the attachment:32804
要允许构建完整附件,您可以采取措施避免literal concatenation
。以下是使用CONCAT
的示例。 (但请注意!你也不能DBMS_OUTPUT
一个巨大的CLOB
,所以这个例子也抓住了那个例外并让你知道。
首先制作测试数据:
CREATE TABLE TESTLEI (
CUSTID NUMBER,
CUSTNAME VARCHAR2(128),
EMAIL VARCHAR2(128)
);
INSERT INTO TESTLEI SELECT
LEVEL,
'Person' || LEVEL,
'email' || LEVEL || '@email.abc'
FROM DUAL
CONNECT BY LEVEL < 1000;
现在我们有999
行。
现在修改块以仅在小字符串上使用||
串联。使用CONCAT
代替大字符串:
DECLARE
V_MESSAGEATT CLOB;
ATTACHMENT_TEXT CLOB;
V_CHAR_COUNT NUMBER;
CURSOR MAIN_CURSOR IS
SELECT
CUSTID,
CUSTNAME,
EMAIL
FROM TESTLEI;
MAIN_CURSOR_VAR MAIN_CURSOR%ROWTYPE;
BEGIN
OPEN MAIN_CURSOR;
LOOP
FETCH MAIN_CURSOR INTO MAIN_CURSOR_VAR;
EXIT WHEN
(MAIN_CURSOR%NOTFOUND);
IF MAIN_CURSOR%ROWCOUNT = 1
THEN
V_MESSAGEATT := V_MESSAGEATT || '<tr><th>user ID</th><th>USERNAME</th><th>EMAILID</th></tr>';
END IF;
V_MESSAGEATT := CONCAT(V_MESSAGEATT, '<tr>');
V_MESSAGEATT := CONCAT(V_MESSAGEATT, '<td>' || MAIN_CURSOR%ROWCOUNT || '</td>');
V_MESSAGEATT := CONCAT(V_MESSAGEATT, '<td>' || MAIN_CURSOR_VAR.CUSTID || '</td>');
V_MESSAGEATT := CONCAT(V_MESSAGEATT, '<td>' || MAIN_CURSOR_VAR.CUSTNAME || '</td>');
V_MESSAGEATT := CONCAT(V_MESSAGEATT, '<td>' || MAIN_CURSOR_VAR.EMAIL || '</td>');
V_MESSAGEATT := CONCAT(V_MESSAGEATT, '</tr>');
ATTACHMENT_TEXT := V_MESSAGEATT;
END LOOP;
DBMS_OUTPUT.PUT_LINE('Finished building attachment!!');
CLOSE MAIN_CURSOR;
DECLARE
V_PRINT_ERROR_CHAR_COUNT NUMBER;
BEGIN
--The clob is too big to print. This will fail.
DBMS_OUTPUT.put_line(ATTACHMENT_TEXT);
EXCEPTION WHEN OTHERS THEN
V_PRINT_ERROR_CHAR_COUNT := DBMS_LOB.getlength(V_MESSAGEATT);
DBMS_OUTPUT.PUT_LINE('The attachment was too long to print in DBMS_OUTPUT. Length:' || V_PRINT_ERROR_CHAR_COUNT);
END;
EXCEPTION WHEN OTHERS THEN
DECLARE
V_ATTACH_ERROR_CHAR_COUNT NUMBER;
BEGIN
V_ATTACH_ERROR_CHAR_COUNT := DBMS_LOB.getlength(V_MESSAGEATT);
DBMS_OUTPUT.PUT_LINE('Failed to build the attachment:' || V_ATTACH_ERROR_CHAR_COUNT);
END;
END;
/
您无法按原样打印CLOB
;如果你真的想打印它,你需要打破它。但是如果你真的打算做一些像发送到另一个功能的东西那么你应该好好去。
当您运行上述内容时,您应该得到类似的内容:
Finished building attachment!!
The attachment was too long to print in DBMS_OUTPUT. Length:77548
PL/SQL procedure successfully completed.