Pesquisar este blog

sexta-feira, 17 de junho de 2011

SPLIT STRING – Função para dividir uma string por um caracter de controle

Imagine a seguinte situação: você possui uma string, separada por ponto e vírgula, e você deseja separar estas strings para realizar um tratamento. Vamos ver um exemplo abaixo:

 

string1; string2; "string 3 com ; no meio"; string4

 

Então nós temos quatro valores concatenados em uma única string. Observe que o terceiro valor utiliza o ponto e vírgula como texto da própria string, porém a sentença toda está entre aspas (“), o que determina que o ponto e virgula desta frase faz parte da string, e não é um caracter separador.

Para resolver esta questão, eu desenvolvi o seguinte procedimento:

 

  1. -- exec spSplit 'string1; string2; "string3 com ; no meio"; string4', ';'
  2. alter proc spSplit
  3.   @grupo varchar(8000),
  4.   @caracter char(1) = NULL
  5. as
  6.  
  7. begin
  8.  
  9.   -- ***************
  10.   -- SQL Burger 2011
  11.   -- Função SPLIT, separa string dividida por
  12.   -- caracter de controle. Esta função só pode ser
  13.   -- utilizada e distribuída caso os créditos ao autor
  14.   -- sejam citados.
  15.   -- ***************
  16.   
  17.   if @caracter is null set @caracter = ','
  18.  
  19.   declare @pos int
  20.   declare @buffer varchar(8000)
  21.   declare @buffer2 varchar(8000)
  22.  
  23.   create table #ret (texto varchar(8000) null, ordem int not null identity(1,1))
  24.  
  25.   while charindex('"', @grupo) > 0
  26.   begin
  27.  
  28.     select @pos = charindex('"', @grupo)
  29.  
  30.     select @buffer = left(@grupo, @pos)
  31.  
  32.     select @grupo = substring(@grupo, @pos + 1, len(@grupo))
  33.  
  34.     select @pos = charindex('"', @grupo)
  35.  
  36.     select @buffer2 = left(@grupo, @pos)
  37.  
  38.     select @grupo = substring(@grupo, @pos + 1, len(@grupo))
  39.  
  40.     select @buffer = replace(@buffer, '"','')
  41.          , @buffer2 = replace(@buffer2, '"', '')
  42.  
  43.     select @buffer2 = replace(@buffer2, @caracter, char(254))
  44.     
  45.     select @buffer2 = replace(@buffer2, ';', char(253))
  46.  
  47.     select @grupo = rtrim(@buffer) + rtrim(@buffer2) + rtrim(@grupo)
  48.  
  49.   end
  50.   
  51.   while charindex(@caracter,@grupo) > 0
  52.   begin
  53.     select @pos = charindex(@caracter,@grupo)
  54.     select @buffer = left(@grupo,@pos - 1)
  55.     select @grupo = right(@grupo,len(rtrim(@grupo)) - @pos)
  56.     
  57.     select @buffer = replace(@buffer, char(254), @caracter)
  58.     select @buffer = replace(@buffer, char(253), ';')
  59.     
  60.     insert into #ret (texto)
  61.       select rtrim(ltrim(@buffer))
  62.   end
  63.  
  64.   if @grupo <> ''
  65.   begin
  66.     select @buffer =replace(@grupo,@caracter,'')
  67.  
  68.     insert into #ret (texto)
  69.       select rtrim(ltrim(@buffer))
  70.   end
  71.  
  72.   select texto from #ret order by ordem
  73.  
  74. end

 

O procedimento recebe dois parâmetros: @grupo (que é string a ser tratada) e @caracter (o caracter de controle a ser utilizado para separar a string). O resultado é o seguinte:

 

  1. exec spSplit 'string1; string2; "string3 com ; no meio"; string4', '!'

 

 image

 

A procedure irá retornar cada string em uma linha, permitindo tratá-las da maneira como quiser. Uma dica, utilize uma tabela temporária com uma coluna auto-numérica, e você saberá exatamente qual linha ler de acordo com a posição desejada:

 

  1. set nocount on
  2.  
  3. create table #split (
  4.   texto varchar(100) null
  5. , ordem int not null identity )
  6.  
  7. insert into #split (texto)
  8.   exec spSplit 'string1; string2; "string3 com ; no meio"; string4', ';'
  9.   
  10. select texto as 'Primeiro parametro' from #split where ordem = 1
  11. select texto as 'Segundo parametro' from #split where ordem = 2
  12. select texto as 'Terceiro parametro' from #split where ordem = 3
  13. select texto as 'Quarto parametro' from #split where ordem = 4
  14.  
  15.  
  16. drop table #split

 

Desta forma, o número da linha corresponderá ao parâmetro:

 

 image

 

Outros caracteres de controle poderão ser utilizados, trazendo o mesmo resultado:

 

  1. exec spSplit 'string1! string2! "string3 com ; no meio"! string4', '!'

 

image

 

  1. exec spSplit 'string1! string2! "string3 com ! no meio"! string4', '!'

 

 image

 

Espero que seja útil!

Nenhum comentário:

Postar um comentário