ORA-06502 clob

时间:2016-05-12 17:53:10

标签: sql oracle clob

我花了一整天时间查看现有的StackOverflow问题和答案,但到目前为止还没有任何效果。

我认为我的问题与所有人的情况略有不同。

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

我使用CLOB存储此返回json字符串,因为它的容量为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;

注意我使用returnString在每个循环上打印出dbms_output.put_line(length(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,怎么会这样?

1 个答案:

答案 0 :(得分:4)

我通过做一些微小的改动来运行代码,它似乎超出了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已经指出的那样。

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