#sql #string #firebird #firebird2.5
#sql #строка #firebird #firebird2.5
Вопрос:
Как разделить строку, разделенную запятыми, на строки внутри процедуры хранения и вставить их в поле таблицы?
Использование Firebird 2.5
Ответ №1:
Я публикую измененную версию Майкла, возможно, это будет кому-то полезно.
Изменения заключаются в:
- SPLIT_STRING — это выбираемая процедура.
- Возможен пользовательский разделитель.
- Он анализирует также случаи, когда разделитель является первым символом в 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 ; ^
Комментарии:
1. Отличная работа @MartjinPieters 🙂
Ответ №2:
Вот пример того, как разделить строку и записать вложенные строки в таблицу:
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
Комментарии:
1. Просто к сведению: это не вернет никакого результата для
AINPUT
like',1,2'
, но вернет три подстроки дляAINPUT
like'1,2,'
.
Ответ №3:
Использовать ПОЗИЦИЮ http://www.firebirdsql.org/refdocs/langrefupd21-intfunc-position.html
и
SUSTRING http://www.firebirdsql.org/refdocs/langrefupd21-intfunc-substring.html
функции в инструкции WHILE DO
Комментарии:
1. Добро пожаловать в Stack Overflow! Хотя теоретически это может дать ответ на вопрос, было бы предпочтительнее включить сюда основные части ответа и предоставить ссылку для справки. Спасибо
Ответ №4:
Я использую аналогичное решение, опубликованное некоторое время назад Иржи Цинкурой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
Ответ №5:
Это выглядит хорошо, за исключением одной вещи, в моем объявлении размера переменной сервера Firebird до 32000 возникает исключение «Превышен предел реализации», поэтому будьте осторожны. Я предлагаю вместо этого использовать текст ПОДТИПА BLOB 🙂
Ответ №6:
Это работает для меня в базе данных Informix:
DROP FUNCTION rrhh:fnc_StringList_To_Table;
CREATE FUNCTION rrhh:fnc_StringList_To_Table (pStringList varchar(250))
RETURNING INT as NUMERO;
/* A esta Funcion le podes pasar una cadena CSV con una lista de numeros
* Ejem: EXECUTE FUNCTION fnc_StringList_To_Table('1,2,3,4');
* y te devolvera una Tabla con dichos numeros separados uno x fila
* Autor: Jhollman Chacon @Cutcsa - 2019 */
DEFINE _STRING VARCHAR(255);
DEFINE _LEN INT;
DEFINE _POS INT;
DEFINE _START INT;
DEFINE _CHAR VARCHAR(1);
DEFINE _VAL INT;
LET _STRING = REPLACE(pStringList, ' ', '');
LET _START = 0;
LET _POS = 0;
LET _LEN = LENGTH(_STRING);
FOR _POS = _START TO _LEN
LET _CHAR = SUBSTRING(pStringList FROM _POS FOR 1);
IF _CHAR <> ',' THEN
LET _VAL = _CHAR::INT;
ELSE
LET _VAL = NULL;
END IF;
IF _VAL IS NOT NULL THEN
RETURN _VAL WITH RESUME;
END IF;
END FOR;
END FUNCTION;
EXECUTE FUNCTION fnc_StringList_To_Table('1,2,3,4');
SELECT * FROM TABLE (fnc_StringList_To_Table('1,2,3,4'));
Комментарии:
1. Вы спасли мне жизнь, большое вам спасибо, я пытался найти что-то подобное, что могло бы работать для Informix.