2011-11-08 8 views

Odpowiedz

10

tutaj próbkę, jak podzielić ciąg i wri TE sub-strings do tabeli:

create procedure SPLIT_STRING (
    AINPUT varchar(8192)) 
as 
declare variable LASTPOS integer; 
declare variable NEXTPOS integer; 
declare variable TEMPSTR varchar(8192); 
begin 
    AINPUT = :AINPUT || ','; 
    LASTPOS = 1; 
    NEXTPOS = position(',', :AINPUT, LASTPOS); 
    while (:NEXTPOS > 1) do 
    begin 
    TEMPSTR = substring(:AINPUT from :LASTPOS for :NEXTPOS - :LASTPOS); 
    insert into new_table("VALUE") values(:TEMPSTR); 
    LASTPOS = :NEXTPOS + 1; 
    NEXTPOS = position(',', :AINPUT, LASTPOS); 
    end 
    suspend; 
end 
+0

fajne. Dziękuję Ci bardzo. –

+0

Uwaga: nie zwróci żadnego wyniku dla 'AINPUT' jak' ', 1,2'', ale zwróci trzy podciągi dla 'AINPUT' jak'' 1,2, ''. – Wodzu

4
+0

Witamy na przepełnienie stosu! Chociaż może to teoretycznie odpowiedzieć na pytanie, [byłoby lepiej] (http://meta.stackexchange.com/q/8259) uwzględnić istotne części odpowiedzi tutaj i podać odnośnik do odsyłacza. Dzięki – codingbadger

10

jestem delegowania zmodyfikowana wersja Michaela, może to być przydatne dla kogoś.

Zmiany są:

  1. SPLIT_STRING jest procedura wyboru.
  2. Niestandardowy ogranicznik jest możliwy.
  3. Analizuje także przypadki, gdy separator jest pierwszym znakiem w P_STRING.
set term^; 
create procedure split_string (
    p_string varchar(32000), 
    p_splitter char(1)) 
returns (
    part varchar(32000) 
) 
as 
    declare variable lastpos integer; 
    declare variable nextpos integer; 
begin 
    p_string = :p_string || :p_splitter; 
    lastpos = 1; 
    nextpos = position(:p_splitter, :p_string, lastpos); 
    if (lastpos = nextpos) then 
     begin 
      part = substring(:p_string from :lastpos for :nextpos - :lastpos); 
      suspend; 
      lastpos = :nextpos + 1; 
      nextpos = position(:p_splitter, :p_string, lastpos); 
     end 
    while (:nextpos > 1) do 
     begin 
      part = substring(:p_string from :lastpos for :nextpos - :lastpos); 
      lastpos = :nextpos + 1; 
      nextpos = position(:p_splitter, :p_string, lastpos); 
      suspend; 
     end 
end^ 
set term ;^
+0

Świetna robota @MartjinPieters :) – hims056

+0

Dzięki @MartijnPieters. – Wodzu

3

To wygląda dobrze z wyjątkiem jednej rzeczy, moim serwerze Firebird deklaracji rozmiarze varchar do 32000 przyczyna "limit przekroczony Implementation" wyjątek więc należy być ostrożnym. Proponuję użyć BLOB SUB_TYPE teletekstu zamiast :)

2

Podobne rozwiązanie używam, opublikowane jakiś czas temu przez Jiri Cincura http://blog.cincura.net/232347-tokenize-string-in-sql-firebird-syntax/

recreate procedure Tokenize(input varchar(1024), token char(1)) 
returns (result varchar(255)) 
as 
declare newpos int; 
declare oldpos int; 
begin 
    oldpos = 1; 
    newpos = 1; 
    while (1 = 1) do 
    begin 
    newpos = position(token, input, oldpos); 
    if (newpos > 0) then 
    begin 
     result = substring(input from oldpos for newpos - oldpos); 
     suspend; 
     oldpos = newpos + 1; 
    end 
    else if (oldpos - 1 < char_length(input)) then 
    begin 
     result = substring(input from oldpos); 
     suspend; 
     break; 
    end 
    else 
    begin 
     break; 
    end 
    end 
end