Oracle
 sql >> база данни >  >> RDS >> Oracle

Заявка на Oracle за намиране на всички срещания на символ в низ

Разширявайки отговора на GolezTrol, можете да използвате регулярни изрази, за да намалите значително броя на рекурсивните заявки, които правите:

 select instr('SSSRNNSRSSR','R', 1, level)
   from dual
connect by level <= regexp_count('SSSRNNSRSSR', 'R')

REGEXP_COUNT() връща броя на съвпаденията на шаблона, в този случай броя пъти R съществува в SSSRNNSRSSR . Това ограничава нивото на рекурсия до точния брой, от който се нуждаете.

INSTR() просто търси индекса на R във вашия низ. level е дълбочината на рекурсията, но в този случай също е нивото th появата на низа, тъй като ограничихме до броя на необходимите рекурси.

Ако низът, който искате да изберете, е по-сложен, можете да използвате регулярни изрази и 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


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Монитор за промяна на таблицата Oracle

  2. Има ли булев тип в базите данни на Oracle?

  3. Използване на LogMiner за намиране на текущи промени

  4. разделен със запетая списък в резултат на оператор select в Oracle

  5. Oracle Apex 5.0 – Показване на статично изображение