为什么这个简单的正则表达式在CLOB大小>时不起作用? 4KB?

时间:2014-05-10 18:04:27

标签: regex oracle plsql oracle11g clob

declare
  c clob := '0123456789ABCDEF';
begin
  c := c||c||c||c; c := c||c||c||c;
  c := c||c||c||c; c := c||c||c||c;
  -- Now length(c) = 4096
  c := regexp_substr(c, '(.*)\1'); --ERROR:No more data to read from socket. Why?
end;

it是个错误吗?

使用varchar2代替clob时,它可以正常工作。

1 个答案:

答案 0 :(得分:2)

我有理由相信这是Oracle中的一个错误,并且与使用的特定正则表达式有关。 In this SQLFiddle我玩了不同长度的CLOB,返回不同长度的字符串,我发现的唯一正则表达式(在我非常详尽的测试中)是由OP提供的。 SQLFiddle的代码是:

create table temp_output(s varchar2(4000));

declare
  c16   clob := '0123456789ABCDEF';
  c64   clob;
  c256  clob;
  c1k   clob;
  c4k   clob;
  c4kp2 clob;  -- 4096 with 'x' at each end
  c4kwx clob;  -- 4095 with 'x' at each end
  c16k  clob;
  c16kwx  clob;  -- 16k with x's embedded
  x     clob := 'x';
  d     clob;
begin
  c64  := c16  || c16  || c16  || c16;
  c256 := c64  || c64  || c64  || c64;
  c1k  := c256 || c256 || c256 || c256;
  c4k  := c1k  || c1k  || c1k  || c1k;
  c4kp2 := x || c4k || x;
  c4kwx := x || SUBSTR(c4k, 1, 4093) || x;  -- 4095 chars total
  c16k := c4k  || c4k  || c4k || c4k;
  c16kwx := c4k || x || c4k || c4k || x || c4k;

  insert into temp_output(s) values ('LENGTH(c4k)=' || LENGTH(c4k));
  insert into temp_output(s) values ('LENGTH(c16k)=' || LENGTH(c16k));

  -- d := regexp_substr(c4kp2, '(.*)\1');  -- ERROR
  -- d := regexp_substr(c4kp2, 'x.*x');  -- No error
  d := regexp_substr(c16kwx, 'x.*x');  -- No error

  insert into temp_output (s) values ('LENGTH(d)=' || LENGTH(d));
  insert into temp_output (s) values (SUBSTR(d, 1, 4000));
end;
/
select * from temp_output
/

我最初的想法是,或许可以通过正则表达式提取的文本数量有一个未公布的限制,但这并不是正确的。

分享并享受。