Funkcja Split w Oracle PL/SQL

Kiedyś podczas pisania procedury SQL potrzebowałem funkcję, która podzieli mi tekst oddzielony przecinkami na części. Wiedziałem, że taka funkcja istnieje w MySQL ( splitstring ) ale w Oracle nie przewidzieli jej. Na własne potrzeby zacząłem poszukiwania gotowych rozwiązań ( moje własne kończyły się fiaskiem ). Google było bardzo pomocne i natrafiłem na stronę http://glosoli.blogspot.com/2006/07/oracle-plsql-function-to-split-strings.html

Poniżej prezentuję kod funkcji split, którą polecam:

create or replace function split (
    the_list varchar2,
    the_index number,
    delim varchar2 :=';'
)
    return varchar2
is
    start_pos number;
    end_pos number;

begin
    if the_index = 1 then
        start_pos := 1;

    elsif the_index < 0 then
        start_pos := instr(the_list, delim, -1, abs(the_index)) + 1;

    else
        start_pos := instr(the_list, delim, 1, the_index - 1);

        if start_pos = 0 then
            return null;
        else
            start_pos := start_pos + length(delim);
        end if;

    end if;

    if the_index < 0 then
        end_pos := instr(the_list, delim, start_pos+1, 1);
    else
        end_pos := instr(the_list, delim, start_pos, 1);
    end if;

    if end_pos = 0 then
        return substr(the_list, start_pos);
    else
        return substr(the_list, start_pos, end_pos - start_pos);
    end if;

end split;

Moja modyfikacja :

create or replace function split (
  (
    par_ciag        VARCHAR2,
    par_rozdzielnik VARCHAR2
  ) RETURN tab_tekst
    PIPELINED IS
    var_pozycja  NUMBER;
    var_ciag     VARCHAR2(32767);
    tab_rezultat tab_tekst;
  BEGIN
    var_ciag     := par_ciag;
    tab_rezultat := tab_tekst();
    LOOP
	 var_pozycja := nvl(instr(var_ciag, par_rozdzielnik), 0);
	 IF var_pozycja > 0
	 THEN
	   PIPE ROW(substr(var_ciag, 1, var_pozycja - 1));
	   var_ciag := substr(var_ciag, var_pozycja + length(par_rozdzielnik));
	 ELSE
	   PIPE ROW(var_ciag);
	   EXIT;
	 END IF;
    END LOOP;
    RETURN;

end split;

Dodatkowo trzeba stworzyć typ

TYPE tab_tekst IS TABLE OF VARCHAR2(4000);

Przykładowe wywołanie

SELECT t.* FROM   TABLE(split('aaa;bbb', ';')) t

Comments are closed.