Firebird procedimento armazenado para concatenar todos os valores de campo de várias linhas

StackOverflow https://stackoverflow.com/questions/183675

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.

Foi útil?

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);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top