sexta-feira, 24 de abril de 2009

Concatenando valores sem utilizar cursores no MS-SQL SERVER

Como desenvolvedores, podemos precisar concatenar valores relacionais em uma única linha. Por exemplo, em um sistema contábil podemos precisar listar no histórico de um lançamento o número das notas fiscais envolvidas, ou concatenar uma lista com o nome dos clientes que estão envolvidos em um determinado relatório.

Podemos realizar esta tarefa facilmente com um cursor, percorrendo os registros e concatenando os valores desejados, porém os cursores podem representar um problema a nível de performance, portanto proponho uma alternativa.

Podemos realizar a mesma tarefa, utilizando apenas uma variável e atribuindo os valores recursivamente a variável.

Vamos entender melhor o assunto com um exemplo. Primeiro, vamos criar uma tabela temporária com alguns valores fictícios.

CREATE TABLE #temp (
Id INT IDENTITY(1,1),
Nome VARCHAR(10)
)

INSERT #temp (Nome)
VALUES ('Rodrigo')

INSERT #temp (Nome)
VALUES ('Rafael')

INSERT #temp (Nome)
VALUES ('Wanderley')


Agora vamos criar uma variável que receberá os valores concatenados. Lembre-se, esta variável deve ser suficientemente grande para receber os valores desejados, sem truncar os dados.

DECLARE @retstr VARCHAR(1000)
SET @retstr = NULL


E por último vamos realizar as atribuições a variável, e mostrar os resultados.

SELECT @retstr = COALESCE(@retstr + ', ','') + COALESCE(Nome,'')
FROM #temp

SELECT @retstr

DROP TABLE #temp


Se você digitou corretamente o script, o resultado final deve ser:

"Rodrigo, Rafael, Wanderley"

4 comentários:

  1. Perfeita solução!
    Precisava concatenar lista de emaisl para utilizar no sql mail para envio automatico.

    Obrigado
    Ricardo
    ricpira@gmail.com

    ResponderExcluir
  2. Muito boa a solução.
    Confesso que preciso estudar a fundo o comando,mas já funcionou.

    Muito obrigado!
    marcelo@bross.com.br

    ResponderExcluir
  3. Prezados, com a experiência descobri um meio talvez mais "moderno" de implementar o mesmo resultado. Este exemplo utiliza os comando FOR XML e a função STUFF, que já exemplifiquei aqui no blog. A vantagem é que para este exemplo abaixo, não é necessário declarar variáveis.


    SELECT STUFF((
    SELECT ',' AS "text()",'"' AS "text()",Nome AS "text()",'"' AS "text()"
    FROM #temp
    ORDER BY 1
    FOR XML PATH('')
    ), 1, 1, '');

    ResponderExcluir
  4. Rodrigo Ribeiro, Valeu pela sua dica... ajudou muito!!!

    ResponderExcluir

Leave your comment here!