sql >> Databasteknik >  >> RDS >> Oracle

Oracle-fråga för att hitta alla förekomster av ett tecken i en sträng

Genom att utöka GolezTrols svar kan du använda reguljära uttryck för att avsevärt minska antalet rekursiva frågor du gör:

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

REGEXP_COUNT() returnerar antalet gånger mönstret matchar, i det här fallet antalet gånger R finns i SSSRNNSRSSR . Detta begränsar nivån av rekursion till det exakta antal du behöver.

INSTR() söker helt enkelt efter indexet för R i din sträng. level är djupet av rekursionen men i det här fallet är det också nivån th förekomst av strängen eftersom vi begränsade till antalet återkommande som krävs.

Om strängen du vill plocka ut är mer komplicerad kan du välja reguljära uttryck och REGEXP_INSTR() i motsats till INSTR() men det blir långsammare (inte mycket) och det är onödigt om det inte krävs.

Enkelt riktmärke enligt önskemål:

De två CONNECT BY-lösningarna skulle indikera att användningen av REGEXP_COUNT är 20 % snabbare på en sträng av denna storlek.

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

Funktionen för pipelined tabell är lite långsammare, även om det skulle vara intressant att se hur den presterar över stora strängar med många matchningar.

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. SQL Server-systemdatabaser – Återställ systemdatabaser

  2. Transaktionsloggövervakning

  3. Observera:Konvertering av array till sträng i

  4. Procedur för att exportera tabell till flera csv-filer