E aí pessoal, tudo belezinha com vocês? Segue um post rápido, só para registrar um assunto que rolou em um grupo de discussão do Telegram há algum tempo atrás e só agora eu resolvi parar para escrever a respeito…

Pense no seguinte cenário:

Eu tenho uma tabela onde uma das colunas é um campo texto (varchar(XXX)), separado por ‘;’ (ou qualquer outro caractere de sua preferência).

Mas porque eu teria isso? Bom, imagine que você crie uma trigger para a fazer sua auditoria e, ao invés de guardar em colunas, você guarda em um varchar as alterações…

O objetivo: Agora mudaram de ideia e precisam fazer com que esse texto retorne como colunas em uma query.

Algo assim:

![](/images/2019/11/20191112_01.png)
Spoiler Alert

Algumas observações:

  • Vou trabalhar com uma quantidade fixa de colunas (supor que o máximo é 6), mas é totalmente possível investigar quantas colunas tem no maior texto, para criar a tabela.
  • Se houver um campo vazio (;;), devo deixar o campo como NULL

Vamos lá…

-- Criando uma CTE, apenas para não criar nenhum objeto físico no banco. 
;with cte_val as 
(
  select * from (values 
    (1,'a;b;;c;d;e'),(2,'x;;y;;z'),(3,'t;u;y;t;d;a'),(4,'a;b;c')
  ) as MinhaTabelaDeOrigem(Codigo, Texto) 
)
select Codigo, [col1], [col2], [col3], [col4], [col5], [col6] 
from (
  select Codigo, 
         NULLIF(value,'') AS value, -- Se eu não fizer essa validação a função STRING_SPLIT vai retornar a linhas como vazias - e não como nulas, que é o que eu preciso
	 concat('col',ROW_NUMBER() over (PARTITION BY Codigo order by Codigo )) AS LINHA 
  from cte_val 
  cross apply STRING_SPLIT(Texto,';') as t 
) z
pivot (max(value) FOR LINHA in ([col1], [col2], [col3], [col4], [col5], [col6])) as pvt

Simples, não? 🙂

Lembrete importante: Devido ao uso do STRING_SPLIT, essa consulta só vai rodar acima do SQL Server 2016.

Valeu pessoal! Bons estudos!