Firebird 2.1 хранимая процедура для объединения текста в несколько строк - PullRequest
3 голосов
/ 25 ноября 2010

Я пытаюсь написать хранимую процедуру для объединения нескольких строк текста вместе, чтобы вернуть его в виде одной строки.Например:

CREATE TABLE TEST (
 ID INTEGER,
 SEQ INTEGER,
 TEXT VARCHAR(255));

COMMIT;

INSERT INTO TEST (ID, SEQ, TEXT) VALUES (1, 1, "LINE 1");
INSERT INTO TEST (ID, SEQ, TEXT) VALUES (1, 2, "LINE 2");
INSERT INTO TEST (ID, SEQ, TEXT) VALUES (1, 3, "LINE 3");

COMMIT;

SET TERM !!;
CREATE PROCEDURE concat_names (iID INTEGER)
  RETURNS (CONCAT VARCHAR(2000))
AS
DECLARE VARIABLE name VARCHAR(255);
BEGIN
  CONCAT = '';
  FOR SELECT TEXT FROM TEST where id=:iID INTO :name
  DO BEGIN
    CONCAT = CONCAT || name;
  END
END!!
SET TERM ;!!

commit;

Однако, когда я запускаю:

select concat from concat_names(1);

Всегда возвращает ноль строк.

Есть идеи?

Ответы [ 3 ]

8 голосов
/ 25 ноября 2010

Вы забыли за SUSPEND. Ваш процесс должен выглядеть так:

SET TERM !!;
CREATE PROCEDURE concat_names (iID INTEGER)
  RETURNS (CONCAT VARCHAR(2000))
AS
DECLARE VARIABLE name VARCHAR(255);
BEGIN
  CONCAT = '';
  FOR SELECT TEXT FROM TEST where id=:iID INTO :name
  DO BEGIN
    CONCAT = CONCAT || name;
  END
  SUSPEND;
END!!
SET TERM ;!!

Вы можете достичь того же результата без сохраненных процедур. Использовать статистическую функцию LIST:

SELECT LIST(text, '') FROM TEST where id=:iID 

Второй параметр LIST - это разделитель. Если вы вызовете LIST только с именем поля, запятая ',' будет использоваться для разделения значений.

0 голосов
/ 06 марта 2016

Без использования Stored Proc и версии Firebird 2.5, функция агрегации LIST вернет "Конкатенация строк через запятую, отличных от NULL, в столбце" *. Используя вышеупомянутую таблицу TEST, SQL

SELECT LIST(TEXT)
    FROM TEST

возвращает

ЛИНИЯ 1, ЛИНИЯ 2, ЛИНИЯ 3

Это может представлять интерес.

* Взято со справочной страницы Firebird здесь

0 голосов
/ 28 ноября 2010

В случае, если поле TEST может иметь нулевое значение, и вы не хотите устанавливать нулевое значение для всего результата, полезно использовать:

 CONCAT = CONCAT || coalesce(name,'');

вместо

CONCAT = CONCAT || name;
...