Reputation: 137
Error report - ORA-06502: PL/SQL: numeric or value error ORA-06512: at line 19 06502. 00000 - "PL/SQL: numeric or value error%s"
IF I COMMENT LINE NUMBER 23 & 24 I'LL GET OUTPUT WHILE I UN-COMMENT I'M GETTING ABOVE ERROR WHILE I TAKE 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;
/
Upvotes: 1
Views: 3887
Reputation: 2480
Though you are dealing with CLOB
datatype, the concatenations are producing literal
s (max length 32,767 bytes), and PL/SQL
won't allow overshooting this max during literal
concatenation.
If TESTLEI
has enough rows, the length of V_MESSAGEATT
in one of the concatenations goes over this limit, and you are given the ORA-06502
. You can see this in action, if you add an exception handler like the below at the end of your block:
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;
/
When you run the above, you should get a message like the following, with a number just over 32767
:
Failed to build the attachment:32804
To allow the full attachment to build, you can take measures to avoid literal concatenation
. Here's an example that uses CONCAT
instead. (But note! you also can't DBMS_OUTPUT
a huge CLOB
either, so this example catches that exception too and lets you know.
First make test data:
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;
Now we have 999
rows.
Now modify the block to only use ||
concatenation on small strings. use CONCAT
instead on big strings:
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;
/
You can't print the CLOB
as-is; if you really want to print it, you'd need to break it up. But if you are really planning to do something like send to another function, you should be good to go.
When you run the above, you should get something like:
Finished building attachment!!
The attachment was too long to print in DBMS_OUTPUT. Length:77548
PL/SQL procedure successfully completed.
Upvotes: 4