Как разделить строку через запятую внутри хранимой процедуры? - PullRequest
8 голосов
/ 09 ноября 2011

Как разбить строку через запятую на строки в процедуре хранения и вставить их в поле таблицы?

Использование Firebird 2.5

Ответы [ 5 ]

10 голосов
/ 09 ноября 2011

Вот пример того, как разбить строку и записать подстроки в таблицу:

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
10 голосов
/ 28 февраля 2013

Я выкладываю модифицированную версию Майкла, может быть, она кому-нибудь пригодится.

Изменения:

  1. SPLIT_STRING - выбираемая процедура.
  2. Возможен пользовательский разделитель.
  3. Он также анализирует случаи, когда разделитель является первым символом в 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 ; ^
4 голосов
/ 09 ноября 2011

Использование ПОЗИЦИЯ http://www.firebirdsql.org/refdocs/langrefupd21-intfunc-position.html

и

SUSTRING http://www.firebirdsql.org/refdocs/langrefupd21-intfunc-substring.html

функции в операторе WHILE DO

3 голосов
/ 21 марта 2013

Выглядит хорошо, за исключением одной вещи, в моем объявлении размера Varchar сервера Firebird, равном 32000, возникает исключение «Превышен предел реализации», поэтому будьте осторожны.Я предлагаю вместо этого использовать BLOB SUB_TYPE TEXT:)

2 голосов
/ 27 мая 2015

Аналогичное решение, которое я использую, опубликованное недавно 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
...