当前位置: 首页 > 知识库问答 >
问题:

ORA-06502:我接受CLOB datatype变量仍然得到此错误

毛峻
2023-03-14
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个答案

杨海
2023-03-14

尽管您正在处理CLOBdatatype,但连接会产生literals(最大长度32,767字节),并且pl/sqlliteral连接期间不允许超调这个最大长度。

如果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

要允许构建完整附件,可以采取措施避免文本串联。下面的示例使用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;

现在修改该块,使其只对小字符串使用级联。对大字符串使用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.
 类似资料:
  • 我做了一些研究,有一个建议可以使用双重 但是现在我得到了ORA-06502/ORA-06512错误: ORA-06502:PL/SQL:erreur numérique ou erreur sur une valeur ORA-06512:àsys.xmltype“,ligne 272 ORA-06512:àligne 1 06502。00000-“PL/SQL:数值或值错误%s” *原因:出现算

  • 我没有发现这段代码中有任何错误,但是eclipse告诉我变量没有初始化。这只是一个警告,但编译后也不起作用。我根本找不到错误,这段代码是100%正确的。请注意,此代码的结构不容易更改,因为下面提供的代码经过简化,因此您没有那么多要阅读的内容;-)

  • 我已将laravel应用程序的时区更改为,并在app.php文件中更改了此时区 但是,当我使用签入生产时区时,我得到的时区是UTC 我如何设置碳原子的时区

  • CORS策略阻止从来源“http://localhost:3000”访问位于“http://localhost:8080/api”的XMLHttpRequest:请求的资源上没有“access-control-allog-origin”标头。 你知道吗?

  • 问题内容: 在这段代码中,最后,我为c1分配了一个值,但是当我打印它时,我在所有c1字段中都得到了null。我为Cliente类写下了代码。我想打印我给c1的所有值,但我不知道为什么在所有字段中都打印null。我使用调试器遵循代码,直到将所有值分配给新变量的语句为止,一切都正确。 问题答案: 你应该改变这个 至 您正在为方法参数而不是字段分配值。同样适用于构造函数中的所有参数。

  • 我正在使用MySQL工作台(5.6.19)。它有几个连接,其中我要访问的表位于“Connection1”(连接名称)中。连接主机:122.0.0.0。我的数据库名是“sorder”。user=“root”,password=“password”,port=3306。 这是我的一段代码: 我的驱动程序连接失败。另外,我不确定我的路径Strin url应该是什么,因为mySQL workbench中有