我需要帮助优化我的代码或提供可提供时间效率结果的替代方案。
我使用Oracle 11GR2 11.2.0.4.0
我正在编写一个包含一个充满HTML源代码的clob并在html标记之间获取文本的包。我按预期工作的代码,但根据clob中内容的大小,它可能需要永远执行。
我理解使用出现参数的 regexp_substr 可能是瓶颈,我相信如果我可以将其迁移到使用位置参数然后它会运行得更快。
我总共有四个函数,其中两个函数用于管理从函数数组列表函数返回的行。
每个列表函数( return_rows_list 或 return_rows_list2 )将以不同方式解析HTML。例如, return_rows_list 将使用子查询因子, return_rows_list2 将使用PL / SQL和变量来存储 regexp_substr 的结果。我创建了 return_rows_list2 函数,以了解哪种方法最快。这两种功能对于任何实际使用场景都是慢的,彼此之间的距离是10秒。
我需要以某种方式替换使用出现参数的 regexp_substr ,而不是使用 regexp_instr 位置参数>
下面的包需要一些源HTML代码才能正常工作。我建议使用任何网页并将源代码输入变量。我使用select语句来输入clob,因为实际上源将大于32767个字符,并且PL / SQL不会接受大于该字符串的字符串文字。
包来源:
CREATE OR REPLACE package pipe_html_contents as
type rows_t is record( rec varchar2(32767));
type t_rows_list is table of rows_t index by binary_integer;
type t_rows_tab is table of rows_t;
function return_rows_list return t_rows_list;
function return_rows return t_rows_tab PIPELINED;
function return_rows2 return t_rows_tab PIPELINED;
function return_rows_list2 return t_rows_list;
end pipe_html_contents;
/
套餐正文:
CREATE OR REPLACE package body pipe_html_contents as
function return_rows return t_rows_tab PIPELINED IS
l_returnValue t_rows_list;
begin
l_returnValue:=return_rows_list;
for i in 1 .. l_returnValue.count loop
pipe row (l_returnValue(i));
end loop;
return;
end;
function return_rows2 return t_rows_tab PIPELINED IS
l_returnValue t_rows_list;
begin
l_returnValue:=return_rows_list2;
for i in 1 .. l_returnValue.count loop
pipe row (l_returnValue(i));
end loop;
return;
end;
function return_rows_list return t_rows_list IS
l_returnValue t_rows_list;
p_clob clob:='';
c_temp clob;
l_count pls_integer := 0;
begin
for l_rec in ( with src as (select (select SOURCE from temp)) as html from dual) --Source HTML Code goes here. Replace the select SOURCE from temp with the source HTML code from your website of choice.
,fields as (select html
,regexp_replace(regexp_replace(html
,'<[^<>]+>'
,'▌')
,'▌+'
,'▌') data
,length(regexp_replace(regexp_replace(regexp_replace(html
,'<[^<>]+>'
,'▌')
,'▌+'
,'▌')
,'[^▌]+'
,''))-2 num_fields
from src)
select trim(regexp_substr(data,'[^▌]+',1,level)) field
from fields
connect by level <= num_fields)
LOOP
if length(l_rec.field) > 2 then
l_count:=l_count +1;
l_returnValue(l_count).rec:=l_rec.field;
end if;
END LOOP;
return l_returnValue;
end;
function return_rows_list2 return t_rows_list IS
l_returnValue t_rows_list;
p_clob clob;
c_temp clob;
l_Matches pls_integer;
v_match clob:=null;
l_count pls_integer := 0;
begin
select SOURCE into p_clob from temp; --Source HTML Code goes here. Replace the select SOURCE into p_clob from temp with the source HTML code from your website of choice.
c_temp:=regexp_replace(regexp_replace(p_clob , '<[^<>]+>' ,'▌'),'^[▌]+' ,'▌');
l_Matches:=length(regexp_replace(regexp_replace(regexp_replace(p_clob, '<[^<>]+>','▌'),'^[▌]+','▌'),'[^▌]+',''))-2;
for i in 1 .. l_Matches
LOOP
v_match:=trim(regexp_substr(c_temp,'[^▌]+',length(regexp_replace(regexp_replace(regexp_replace(c_temp, '<[^<>]+>','▌'),'^[▌]+','▌'),'[^▌]+',''))+1,i));
if length(v_match) > 2 then
l_count:= l_count+1;
l_returnValue(l_count).rec:=v_match;
end if;
END LOOP;
return l_returnValue;
exception
when others then
dbms_output.put_line(sqlerrm);
end;
end pipe_html_contents;
/
用法示例:
select * from table(pipe_html_contents.return_rows); -- for sub-query factoring
select * from table(pipe_html_contents.return_rows2); -- for Make shift sub-query facoring