Firebird procedimento armazenado para concatenar todos os valores de campo de várias linhas
-
06-07-2019 - |
Pergunta
meu objetivo é escrever um proc armazenado que pode coletar todos os valores de campo de várias linhas em uma variável de saída única (talvez varchar (some_length)). Pode parecer estranho, mas solução eu tenho bastante positiva a sua a única que pode usar em que situação im. Eu não usei Firebird antes e procedimentos armazenados olhar muito diferente do que em outros sistemas db conhecido poços. Meu Firebird é de 1,5 e dialeto 3 (não sei o que isso significa). Então, talvez alguém poderia me ajudar com um exemplo algoritmo.
Solução
O procedimento a seguir faz o que você descreve:
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;
Mas eu questionar a sabedoria desta solução. Como você sabe o VARCHAR é longo o suficiente para todas as linhas em seu conjunto de dados desejado?
É muito mais fácil e mais seguro para executar uma consulta para devolver o resultado para uma linha de aplicação por linha. Toda linguagem de programação de aplicações tem métodos para cordas concatenar, mas o mais importante é que eles têm métodos mais flexíveis para gerenciar o crescimento de dados.
A propósito, "dialeto" no Firebird e InterBase refere-se a um modo de compatibilidade que foi introduzido para que os aplicativos desenvolvidos para InterBase 5.x pode trabalhar com versões posteriores do InterBase e Firebird. Isso foi há quase dez anos atrás, e AFAIK não há necessidade hoje para usar qualquer coisa menor do que dialeto 3.
Outras dicas
Você tem que testar para valores nulos quando concatenando, aqui está um exemplo para dois campos e um separador entre eles:
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
Retornando múltiplas linhas usando procedimentos Firebird armazenados é muito, muito fácil.
Não use:
execute procedure proc_name(value);
Em vez disso usar o:
select * from proc_name(value);