扩展 GolezTrol 的答案,您可以使用正则表达式来显着减少您执行的递归查询的数量:
select instr('SSSRNNSRSSR','R', 1, level)
from dual
connect by level <= regexp_count('SSSRNNSRSSR', 'R')
REGEXP_COUNT()返回模式匹配的次数,在这种情况下,次数R
存在于SSSRNNSRSSR
. 这将递归级别限制为您需要的确切数字。
INSTR()只是在字符串中搜索 R 的索引。level
是递归的深度,但在这种情况下,它也是字符串的第 th级出现,因为我们限制了所需的递归次数。
如果您要挑选的字符串更复杂,您可以使用正则表达式 ans REGEXP_INSTR()而不是 INSTR() 但它会更慢(不是很多),除非需要,否则它是不必要的。
根据要求进行简单的基准测试:
两个 CONNECT BY 解决方案表明,在这种大小的字符串上使用 REGEXP_COUNT 快 20%。
SQL> set timing on
SQL>
SQL> -- CONNECT BY with REGEX
SQL> declare
2 type t__num is table of number index by binary_integer;
3 t_num t__num;
4 begin
5 for i in 1 .. 100000 loop
6 select instr('SSSRNNSRSSR','R', 1, level)
7 bulk collect into t_num
8 from dual
9 connect by level <= regexp_count('SSSRNNSRSSR', 'R')
10 ;
11 end loop;
12 end;
13 /
PL/SQL procedure successfully completed.
Elapsed: 00:00:03.94
SQL>
SQL> -- CONNECT BY with filter
SQL> declare
2 type t__num is table of number index by binary_integer;
3 t_num t__num;
4 begin
5 for i in 1 .. 100000 loop
6 select pos
7 bulk collect into t_num
8 from ( select substr('SSSRNNSRSSR', level, 1) as character
9 , level as pos
10 from dual t
11 connect by level <= length('SSSRNNSRSSR') )
12 where character = 'R'
13 ;
14 end loop;
15 end;
16 /
PL/SQL procedure successfully completed.
Elapsed: 00:00:04.80
流水线表函数要慢一些,但看看它如何在具有大量匹配项的大字符串上执行会很有趣。
SQL> -- PIPELINED TABLE FUNCTION
SQL> declare
2 type t__num is table of number index by binary_integer;
3 t_num t__num;
4 begin
5 for i in 1 .. 100000 loop
6 select *
7 bulk collect into t_num
8 from table(string_indexes('SSSRNNSRSSR','R'))
9 ;
10 end loop;
11 end;
12 /
PL/SQL procedure successfully completed.
Elapsed: 00:00:06.54