ORA-06502 clob 的数字或值错误构建字符串

ORA-06502 numeric or vlaue error building string for clob

我一整天都在查看现有的 Whosebug 问题和答案,但到目前为止没有任何效果。

我认为我的问题与其他人的略有不同。

我正在根据数据库中的 SELECT 构建一个 JSON 字符串。这需要能够处理 50k+ 记录。我正在使用 11g,但它也会部署在 10g 上。

我用一个CLOB来存储这个returnjson字符串,因为它有4GB的容量。但是,我不断收到错误消息:ORA-06502: PL/SQL: numeric or value error。以前我在将 varchar 附加到我的 clob 时遇到此错误,例如 returnString := returnString || "some text; 所以我相信它是将 clob 转换为 varchar 并导致此错误。从那时起,我通过使用 dbms_log.append()

摆脱了我认为可能发生演员表的任何地方

这是我的 PL/SQL:

declare

  v_person_code ca_mips_queue.person_code%type;
  v_person_type ca_mips_queue.person_type%type;

  cursor cur_mips is
    select person_code,person_type from ca_mips_queue 
    where terminal_code = :terminal_code and (download_stage='1' or download_stage = '2');

  returnString clob;
  v_isFirst boolean := TRUE;

begin

  dbms_lob.createtemporary(returnString, true);
  dbms_lob.open(returnString, DBMS_LOB.LOB_READWRITE);
  dbms_lob.append(returnString, '{"items":[');

  for person_rec in cur_mips
  loop
      v_person_code := person_rec.person_code;
      v_person_type := person_rec.person_type;

      update ca_mips_queue
      set download_stage = '2'
      where terminal_code = :terminal_code
      and person_code = v_person_code
      and person_type = v_person_type;

      if v_isFirst then
          dbms_lob.append(returnString, '{"person_code": "');
          v_isFirst := FALSE;
      else
          dbms_lob.append(returnString,  ',{"person_code": "');
      end if;

      dbms_lob.append(returnString, v_person_code);
      dbms_lob.append(returnString, '", "person_type": "');
      dbms_lob.append(returnString, v_person_type);
      dbms_lob.append(returnString, '"}');

      dbms_output.put_line(length(returnString));

  end loop;

  commit;

  dbms_lob.append(returnString, ']}');
  :result := returnString;

  dbms_lob.close(returnString);

  :status_code := 200;

  exception 
    when others then
      :status_code := 500;
      :exception := SQLERRM;
      DBMS_OUTPUT.PUT_LINE(:exception);

end;

注意我在每个循环中使用 dbms_output.put_line(length(returnString)); 打印出 returnString 的大小 这是它的输出(或最后几个):

43933
43976
44019
44062
44105
44148
44191
44234
44277
44320
44363
44406
44449
44492
44535
44578
44621
44664
44707
44750
44793
44836
44879
44922
44965
45008
ORA-06502: PL/SQL: numeric or value error

看来它在大约 45008 字节(450kb?)时遇到了麻烦。

如果 clob 有 4GB 的限制,这怎么可能?

我 运行 对代码做了一些细微的改动,它似乎可以超过 450kb。

declare

  v_person_code ca_mips_queue.person_code%type;
  v_person_type ca_mips_queue.person_type%type;

  cursor cur_mips is
    select person_code,person_type from ca_mips_queue;

  returnString clob;
  v_isFirst boolean := TRUE;

begin

  dbms_lob.createtemporary(returnString, true);
  dbms_lob.open(returnString, DBMS_LOB.LOB_READWRITE);
  dbms_lob.append(returnString, '{"items":[');

  for person_rec in cur_mips
  loop
      v_person_code := person_rec.person_code;
      v_person_type := person_rec.person_type;

      if v_isFirst then
          dbms_lob.append(returnString, '{"person_code": "');
          v_isFirst := FALSE;
      else
          dbms_lob.append(returnString,  ',{"person_code": "');
      end if;

      dbms_lob.append(returnString, v_person_code);
      dbms_lob.append(returnString, '", "person_type": "');
      dbms_lob.append(returnString, v_person_type);
      dbms_lob.append(returnString, '"}');

      dbms_output.put_line(length(returnString));

  end loop;

  commit;

  dbms_lob.append(returnString, ']}');
--  :result := returnString;

  dbms_lob.close(returnString);

  :status_code := 200;

end;

这是最后几行的输出。

146471
146545
146639
146726
146803
146880
146958
147036
147116
147194
147267
147350
147419
147489
147559
147630
147706
147778
147850
147923
147995
148068
148135
148203
148278
148360
148437
148510
148585
148666
148746
148821
148899
148985
149060
149137
149211
149305

Statement processed.

请注意,我已经评论了以下行。

:result := returnString;

所以我想说问题不在于 Alex Poole 已经指出的循环。

能否在您的代码中尝试这些更改。