ORA-06502:我接受CLOB数据类型变量仍然出现此错误

时间:2017-09-30 16:32:53

标签: oracle plsql oracle11g

错误报告 - 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;
/

1 个答案:

答案 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.
相关问题