2008-10-08 4 views
5

Моя цель состоит в том, чтобы написать сохраненный процесс, который может собирать все значения полей из нескольких строк в одну единственную выходную переменную (возможно, varchar (some_length)). Это может показаться странным решением, но я вполне уверен, что это единственное, что я могу использовать в этой ситуации. Я не использовал Firebird раньше, а хранимые процессы выглядели иначе, чем в других хорошо известных системах db. My Firebird - 1,5 и диалект 3 (не уверен, что это значит). Так что, может быть, кто-то может помочь мне с примером алгоритма.Хранимая процедура Firebird для конкатенации всех значений полей из нескольких строк

ответ

5

Следующая процедура делает то, что вы описали:

SET TERM !!; 
CREATE PROCEDURE concat_names 
    RETURNS (concat VARCHAR(2000)) 
AS 
DECLARE VARIABLE name VARCHAR(100); 
BEGIN 
    concat = ''; 
    FOR SELECT first_name || ' ' || last_name FROM employee INTO :name 
    DO BEGIN 
    concat = concat || name || ', '; 
    END 
END!! 
SET TERM ;!! 
EXECUTE PROCEDURE concat_names; 

Но я подвергаю сомнению мудрость этого решения. Как вы знаете, что VARCHAR достаточно длинный для всех строк в вашем желаемом наборе данных?

Гораздо проще и безопаснее запускать запрос для возврата результата в приложение по строкам. У каждого языка программирования приложений есть методы для конкатенации строк, но что более важно, у них есть более гибкие методы управления ростом данных.

Кстати, «диалект» в Firebird и InterBase относится к режиму совместимости, который был введен, чтобы приложения, разработанные для InterBase 5.x, могли работать с более поздними версиями InterBase и Firebird. Это было почти десять лет назад, и AFAIK нет никакой необходимости сегодня использовать что-то ниже, чем диалект 3.

+0

Если вы используете Firebird 2.1, вы можете использовать функцию совокупного LIST с обеспечивает текстовую BLOB в результате. То есть нет предела поля varchar. – 2008-10-08 19:42:32

0

Вы должны проверить нулевые значения при конкатенации, вот пример для двух полей и разделитель между ними:

CREATE PROCEDURE CONCAT(
    F1 VARCHAR(385), 
    F2 VARCHAR(385), 
    SEPARATOR VARCHAR(10)) 
RETURNS (
    RESULT VARCHAR(780)) 
AS 
begin 

    if ((:f1 is not null) and (:f1 <> '')) then 
    result = :f1; 

    if ((:f2 is not null) and (:f2 <> '')) then 
    if ((result is not null) and (result <> '')) then 
     begin 
     if ((:separator is not null) and (separator <> '')) then 
      result = result||separator||f2; 
     else 
      result = result||f2; 
     end 
    else 
     result = f2; 

    suspend; 
end 
0

Возвращение нескольких строк с использованием хранимых процедур Firebird очень просто.

Не используйте:

execute procedure proc_name(value); 

Вместо этого используйте:

select * from proc_name(value);