我在表格中的CLOB中有下面的文字
表名:tbl1
列
col1 - 数字(主键)
col2 - clob(如下)
列#1
-----
Col1 = 1
Col2 =
1331882981,ab123456,这里的一些文字
它可以运行多行并且有很多文本...
~1331890329,pqr123223,更多文字......
列#2
-----
Col1 = 2
Col2 =
1331882981,abc333,这里的一些文字
它可以运行多行并且有很多文本...
~1331890329,pqrs23,更多文字......
现在我需要知道如何才能得到低于输出的信息
Col1值
---- ---------------------
1 1331882981,ab123456
1 1331890329,pqr123223
2 1331882981,abc333
2 1331890329,pqrs23
([0-9] {10},[a-z 0-9] +。),==>这是匹配“1331890329,pqrs23”的正则表达式,我需要知道如何替换哪些不匹配此正则表达式然后将它们分成多行
修改#1
我在Oracle 10.2.0.5.0上,因此不能使用REGEXP_COUNT函数:-(另外,col2是一个很大的CLOB
修改#2
我试过下面的查询,它适用于某些记录(即如果我添加“where”子句)。但是当我删除“where”时,它永远不会返回任何结果。我试图将它放入一个视图并插入一个表并让它一夜之间运行但仍然没有完成:(
with t as (select col1, col2 from temp_table)
select col1,
cast(substr(regexp_substr(col2, '[^~]+', 1, level), 1, 50) as
varchar2(50)) data
from t
connect by level <= length(col2) - length(replace(col2, '~')) + 1
修改#3
# of Chars in Clob Total ----------- ----- 0 - 1k 3196 1k - 5k 2865 5k - 25k 661 25k - 100k 36 > 100k 2 ----------- ----- Grand Total 6760
我有~7k行的clobs,其分布如上所示...
答案 0 :(得分:1)
好吧,你可以试试像:
with v as
(
select 1 col1, '1331882981,ab123456,Some text here
which can run multiple lines and have a lot of text...
~1331890329,pqr123223,Some more text...' col2 from dual
union all
select 2 col1, '133188298777,abc333,Some text here
which can run multiple lines and have a lot of text...
~1331890329,pqrs23,Some more text...' col2 from dual
)
select distinct col1, regexp_substr(col2, '([0-9]{10},[a-z 0-9]+)', 1, level) split
from v
connect by level <= REGEXP_COUNT(col2, '([0-9]{10},[a-z0-9]+)')
order by col1
;
这给出了:
1 1331882981,ab123456
1 1331890329,pqr123223
2 1331890329,pqrs23
2 3188298777,abc333
编辑 10g,REGEXP_COUNT
不存在,但您有workarounds。在这里,我替换了我希望在文本中找不到的模式(这里,XYZXYZ
,但你可以选择更复杂的东西来自信),做一个具有相同匹配的差异但被替换为空字符串,然后除以我的模式长度(此处为6
):
with v as
(
select 1 col1, '1331882981,ab123456,Some text here
which can run multiple lines and have a lot of text...
~1331890329,pqr123223,Some more text...' col2 from dual
union all
select 2 col1, '133188298777,abc333,Some text here
which can run multiple lines and have a lot of text...
~1331890329,pqrs23,Some more text...' col2 from dual
)
select distinct col1, regexp_substr(col2, '([0-9]{10},[a-z 0-9]+)', 1, level) split
from v
connect by level <= (length(REGEXP_REPLACE(col2, '([0-9]{10},[a-z 0-9]+)', 'XYZXYZ')) - length(REGEXP_REPLACE(col2, '([0-9]{10},[a-z 0-9]+)', ''))) / 6
order by col1
;
编辑2: CLOB(以及一般的LOB)和正则表达似乎不太合适:
ORA-00932: inconsistent datatypes: expected - got CLOB
将CLOG转换为字符串(regexp_substr(to_char(col2), ...
)似乎解决了这个问题。
编辑3: CLOB也不喜欢distinct
,因此在嵌入式请求中将split result转换为char,然后在上层请求中使用distinct
成功!
select distinct col1, split from
(
select col1, to_char(regexp_substr(col2, '([0-9]{10},[a-z 0-9]+)', 1, level)) split
from temp_epn
connect by level <= (length(REGEXP_REPLACE(col2, '([0-9]{10},[a-z 0-9]+)', 'XYZXYZ')) - length(REGEXP_REPLACE(col2, '([0-9]{10},[a-z 0-9]+)', ''))) / 6
order by col1
);
答案 1 :(得分:0)
以上解决方案无效,以下是我的工作。
update temp_table set col2=regexp_replace(col2,'([0-9]{10},[a-z0-9]+)','(\1)') ;
update temp_table set col2=regexp_replace(col2,'\),[\s\S]*~\(','(\1)$');
update temp_table set col2=regexp_replace(col2,'\).*?\(','$');
update temp_table set col2=replace(regexp_replace(col2,'\).*',''),'(','');
在这4个更新命令之后,col2将具有类似
的内容1 1331882981,ab123456$1331890329,pqr123223
2 1331882981,abc333$1331890329,pqrs23
然后我写了一个函数来分割这个东西。我选择该功能的原因是拆分“$”以及col2仍然具有> 10k字符的事实
create or replace function parse( p_clob in clob ) return sys.odciVarchar2List
pipelined
as
l_offset number := 1;
l_clob clob := translate( p_clob, chr(13)|| chr(10) || chr(9), ' ' ) || '$';
l_hit number;
begin
loop
--Find occurance of "$" from l_offset
l_hit := instr( l_clob, '$', l_offset );
exit when nvl(l_hit,0) = 0;
--Extract string from l_offset to l_hit
pipe row ( substr(l_clob, l_offset , (l_hit - l_offset)) );
--Move offset
l_offset := l_hit+1;
end loop;
end;
然后我打电话给
select col1,
REGEXP_SUBSTR(column_value, '[^,]+', 1, 1) col3,
REGEXP_SUBSTR(column_value, '[^,]+', 1, 2) col4
from temp_table, table(parse(temp_table.col2));