Usuário com melhor resposta
Separa valores de campo varchar

Pergunta
-
Srs.,
Tenho uma tabela onde tenho um campo DESCRICAO, do tipo varchar.
Um registro deste campo, tem uma quantidade indefinida de Descrições, e estas são separadas por ";" - PONTO E VIRGULA
Ex:
ID Descricao
1 teste; teste1; teste2
2 sql; sql1; sql2
3 comp; comp1; comp2
Eu preciso criar uma tabela associativa e buscar os dados nesta tabela anterior, ficando eles da seguinte forma:
ID Descricao
1 teste
1 teste1
1 teste2
2 sql
2 sql1
2 sql2
3 comp
3 comp1
3 comp2
Enfim, preciso pegar cada valor (separados por ponto e virgula) do campo descrição e criar-lo como um novo resgistro nesta nova tabela.
Preciso de ajuda
Agradeço.
Respostas
-
Boa noite Rafael,
Se você garantir que esses campos tem um padrão na separação por ponto e vírgula, você pode usar algo parecido com o exemplo abaixo.
Eu tomei como premissa que sempre haverá um espaço após o ';' e que ele sempre será o último caractere do texto.
Esse exemplo é pra você entender como pode fazer. Customize-o para atender às suas necessidades.CREATE TABLE #tmp ( Palavras VARCHAR(100) ) DECLARE @TEXTO VARCHAR(200) SET @TEXTO = 'SQL; SQL1; SQL2; TESTE;' WHILE (LEN(@Texto) > 0) BEGIN insert into #tmp SELECT SUBSTRING(@TEXTO, 0, patindex('%;%', @texto)) set @TEXTO = SUBSTRING(@TEXTO, patindex('%;%', @texto) + 2, LEN(@TEXTO) ) PRINT @TExto END SELECT * FROM #tmp
[]'s
Mariana Del Nero /* Se a resposta foi útil, não esqueça de marcá-la */
- Marcado como Resposta Heloisa Pires segunda-feira, 26 de março de 2012 14:50
-
Boa Noite,
Segue uma alternativa mais declarativa.
declare @t table (ID INT, Descricao VARCHAR(50))
insert into @t values (1,'teste; teste1; teste2')
insert into @t values (2,'sql; sql1; sql2')
insert into @t values (3,'comp; comp1; comp2');With Res (Id, DescXML) As
(select ID, cast('<E><e>' + REPLACE(Descricao,'; ','</e><e>') + '</e></E>' as XML)
from @t)SELECT ID, E.e.value('.','nvarchar(30)')
FROM Res
CROSS APPLY DescXml.nodes('/E/e') E(e)[ ]s,
Gustavo Maia Aguiar
Blog: http://gustavomaiaaguiar.wordpress.com
Vídeos:http://www.youtube.com/user/gmasqlClassifique as respostas. O seu feedback é imprescindível
- Marcado como Resposta Heloisa Pires segunda-feira, 26 de março de 2012 14:51
-
Rafael,
Sempre que preciso disso uso a função que vou postar aqui. Ela recebe como parametro o texto que você quer pegar os valores, e o delimitador (o ";" está como padrão), e retorna uma variável do tipo tabela com os valores já separados.
CREATE FUNCTION dbo.Split ( @Texto VARCHAR(MAX), @Caractere VARCHAR(MAX) = ';' ) RETURNS @Saida TABLE (Array VARCHAR(8000)) BEGIN DECLARE @Pt VARCHAR(8000) WHILE CHARINDEX(@Caractere, @Texto, 0) <> 0 BEGIN SELECT @Pt = RTRIM(LTRIM(SUBSTRING(@Texto, 1, CHARINDEX(@Caractere, @Texto, 0) -1))), @Texto = RTRIM(LTRIM(SUBSTRING(@Texto, CHARINDEX(@Caractere, @Texto, 0)+ LEN(@Caractere), LEN(@Texto)))) IF LEN(@Pt) > 0 BEGIN INSERT INTO @Saida SELECT @Pt END END IF LEN(@Texto) > 0 BEGIN INSERT INTO @Saida SELECT @Texto END RETURN END GO
- Editado Philipe Souza quarta-feira, 21 de março de 2012 03:38 Faltou complemento
- Sugerido como Resposta Philipe Souza quarta-feira, 21 de março de 2012 03:38
- Marcado como Resposta Heloisa Pires segunda-feira, 26 de março de 2012 14:51
Todas as Respostas
-
Boa noite Rafael,
Se você garantir que esses campos tem um padrão na separação por ponto e vírgula, você pode usar algo parecido com o exemplo abaixo.
Eu tomei como premissa que sempre haverá um espaço após o ';' e que ele sempre será o último caractere do texto.
Esse exemplo é pra você entender como pode fazer. Customize-o para atender às suas necessidades.CREATE TABLE #tmp ( Palavras VARCHAR(100) ) DECLARE @TEXTO VARCHAR(200) SET @TEXTO = 'SQL; SQL1; SQL2; TESTE;' WHILE (LEN(@Texto) > 0) BEGIN insert into #tmp SELECT SUBSTRING(@TEXTO, 0, patindex('%;%', @texto)) set @TEXTO = SUBSTRING(@TEXTO, patindex('%;%', @texto) + 2, LEN(@TEXTO) ) PRINT @TExto END SELECT * FROM #tmp
[]'s
Mariana Del Nero /* Se a resposta foi útil, não esqueça de marcá-la */
- Marcado como Resposta Heloisa Pires segunda-feira, 26 de março de 2012 14:50
-
Boa Noite,
Segue uma alternativa mais declarativa.
declare @t table (ID INT, Descricao VARCHAR(50))
insert into @t values (1,'teste; teste1; teste2')
insert into @t values (2,'sql; sql1; sql2')
insert into @t values (3,'comp; comp1; comp2');With Res (Id, DescXML) As
(select ID, cast('<E><e>' + REPLACE(Descricao,'; ','</e><e>') + '</e></E>' as XML)
from @t)SELECT ID, E.e.value('.','nvarchar(30)')
FROM Res
CROSS APPLY DescXml.nodes('/E/e') E(e)[ ]s,
Gustavo Maia Aguiar
Blog: http://gustavomaiaaguiar.wordpress.com
Vídeos:http://www.youtube.com/user/gmasqlClassifique as respostas. O seu feedback é imprescindível
- Marcado como Resposta Heloisa Pires segunda-feira, 26 de março de 2012 14:51
-
Rafael,
Sempre que preciso disso uso a função que vou postar aqui. Ela recebe como parametro o texto que você quer pegar os valores, e o delimitador (o ";" está como padrão), e retorna uma variável do tipo tabela com os valores já separados.
CREATE FUNCTION dbo.Split ( @Texto VARCHAR(MAX), @Caractere VARCHAR(MAX) = ';' ) RETURNS @Saida TABLE (Array VARCHAR(8000)) BEGIN DECLARE @Pt VARCHAR(8000) WHILE CHARINDEX(@Caractere, @Texto, 0) <> 0 BEGIN SELECT @Pt = RTRIM(LTRIM(SUBSTRING(@Texto, 1, CHARINDEX(@Caractere, @Texto, 0) -1))), @Texto = RTRIM(LTRIM(SUBSTRING(@Texto, CHARINDEX(@Caractere, @Texto, 0)+ LEN(@Caractere), LEN(@Texto)))) IF LEN(@Pt) > 0 BEGIN INSERT INTO @Saida SELECT @Pt END END IF LEN(@Texto) > 0 BEGIN INSERT INTO @Saida SELECT @Texto END RETURN END GO
- Editado Philipe Souza quarta-feira, 21 de março de 2012 03:38 Faltou complemento
- Sugerido como Resposta Philipe Souza quarta-feira, 21 de março de 2012 03:38
- Marcado como Resposta Heloisa Pires segunda-feira, 26 de março de 2012 14:51
-
Bom Dia,
Algumas considerações sobre o uso de funções:
Funções Escalares – Resusabilidade, Formatação, Preguiça vs Desempenho
http://gustavomaiaaguiar.wordpress.com/2011/05/29/funes-escalares-resusabilidade-formatao-preguia-vs-desempenho/[ ]s,
Gustavo Maia Aguiar
Blog: http://gustavomaiaaguiar.wordpress.com
Vídeos:http://www.youtube.com/user/gmasqlClassifique as respostas. O seu feedback é imprescindível