Oi! Seja bem-vindo!

Hoje estudaremos como fazer SPLIT de string no SQL Server através de 3 técnicas: Com a função split_string do SQL2016. Com uma função 100% em SQL. E com métodos XML.

O que é SPLIT de String

Muitas vezes temos informações dispostas em um texto, que precisam ser separadas para simplificar o processamento. Por exemplo, vamos supor que você precisa criar um glossário a partir desse texto que você está lendo. Como você precisará dar uma definição para cada palavra, o primeiro passo é separar as palavras uma a uma:

Best value for money leggings for fitness with booty – #Adessonews Funding, Subsidies, Regulations and Taxes npp benefits leap fitness group – android app publisher – apkgoogle.net

Muitas

Vezes

Temos

Informações

A seguir, você poderia incluir “:” ao lado de cada palavra, remover virgulas e pontos, e então fornecer uma descrição para cada palavra. O ato inicial (passo 1) de dividir o texto em várias linhas é conhecido como SPLIT de String no mundo da programação, e como você pode ver, tem aplicação prática até mesmo nesse singelo texto.

Utilidade e aplicações de um SPLIT

As aplicações são as mais variadas. Um caso onde vejo ocorrer muito, é quando um programa precisa enviar para outro um conjunto de informações que variam em número de itens. Por exemplo: Sua lista de compras.

Supomos que você tem um aplicativo que envia sua lista de compras para o supermercado. Sua lista de compras varia, em um dia pode haver apenas 1 item, na outra pode haver 100. Em geral, os programas se comunicam através da passagem de parâmetros, como no exemplo abaixo:

Programa_que_recebe_lista_de_compras (nome_do_cliente, produto1, produto2, produto3, …., produtoN)

O problema de usar o modelo acima é que o programa não sabe se virão 1 ou 100 itens, então o ideal é termos uma configuração desse tipo:

Programa_que_recebe_lista_de_compras (nome_do_cliente, Lista_de_produtos)

Sendo a lista de produtos um texto, precisamos combinar uma forma de “delimitar” as compras para que o programa entenda a diferença entre “suco de maça” (que é um produto com 3 palavras) e “maça verde” (outro produto, porém com 2 palavras). Para isso podemos usar um texto delimitado (ou XML, que será papo para outro vídeo):

Programa_que_recebe_lista_de_compras (“Fulano de Tal”, “suco de maça; maça verde; leite; ovos”)

Como fazer SPLIT de String no SQL Server

Aqui vai o script que usei no vídeo, mostrando como fazer SPLIT em Strings no SQL Server:


------------------------------------------------------------------
-- Como fazer SPLIT no SQL Server
------------------------------------------------------------------
/*
= O que é Split?
Transformar um texto delimitado (exemplo: "João;Maria;José;Oscar") em vários textos individuais.

= Exemplo:
"João;Maria;José;Oscar" => nomes de pessoas delimitados por ;

*/
--------------------------------------------------
-- Requisitos para nosso teste
--------------------------------------------------
-- Banco de testes
use master
if db_id('curso') is not null
	drop database curso
go
create database curso
go
use curso
go

--------------------------------------------------
-- Split SQL2016+
--------------------------------------------------
-- Split simples - para tabela
select
	value as nome
from string_split('João;Maria;José;Oscar', ';')

-- Split multi - string functions
select
	left(pessoa, charindex('|', pessoa) - 1) as nome,
	right(pessoa, charindex('|', reverse(pessoa)) - 1) as idade,
	parsename(replace(pessoa,'|','.'), 2) as parse_nome, -- parsename: 1 objeto, 2 schema, 3 banco, 4 servidor
    parsename(replace(pessoa,'|','.'), 1) as parse_idade
from (
	select
		value as pessoa
	from string_split('João|20;Maria|19;José|22;Oscar|16', ';')
) pessoas

-- Split simples - para array (em colunas)
select
	*
from (
	select
		row_number() over (order by (select null)) as posicao,
		value as nome
	from string_split('João;Maria;José;Oscar', ';')
) em_linha
pivot (
	max(nome)
	for	posicao in ([1], [2], [3], [4]) -- explico em outro vídeo como definir colunas dinamicamente...
) em_coluna

--------------------------------------------------
-- Split SQL2008+
--------------------------------------------------
-- Função split manual
go
create function fSplit (@string varchar(max), @separador char(1))
returns table as return
	with a as (
		select
			id = 1,
			len_string = len(@string) + 1,
			ini = 1,
			fim = coalesce(nullif(charindex(@separador, @string, 1), 0), len(@string) + 1),
			elemento = ltrim(rtrim(substring(@string, 1, coalesce(nullif(charindex(@separador, @string, 1), 0), len(@string) + 1)-1)))
		union all
		select
			id + 1,
			len(@string) + 1,
			convert(int, fim) + 1,
			coalesce(nullif(charindex(@separador, @string, fim + 1), 0), len_string),
			ltrim(rtrim(substring(@string, fim + 1, coalesce(nullif(charindex(@separador, @string, fim + 1), 0), len_string)-fim-1)))
		from a where fim < len_string)
	select id, elemento from a
	-- incluir with option (maxrecursion 0) na chamada da FC para strings com mais de 100 elementos
go

-- Split simples
select * from fSplit('João;Maria;José;Oscar', ';')

-- Split multi
select
	left(elemento, charindex('|', elemento) - 1) as nome,
	right(elemento, charindex('|', reverse(elemento)) - 1) as idade
from dbo.fSplit('João|20;Maria|19;José|22;Oscar|16', ';')
go

-- Split multi - XML
declare @p varchar(1000) = 'João|20;Maria|19;José|22;Oscar|16'
print @p
set @p = '<pessoas><pessoa><nome>' + replace(@p, '|', '</nome><idade>')
set @p = replace(@p, ';', '</idade></pessoa><pessoa><nome>') + '</idade></pessoa></pessoas>'
print @p

declare @pessoas xml = @p
select @pessoas
select
    p.pessoa.value('nome[1]','varchar(10)') as nome,
    p.pessoa.value('idade[1]','smallint') as idade
from @pessoas.nodes('pessoas/pessoa') p(pessoa)
go

--------------------------------------------------
-- Excluindo dados de teste
--------------------------------------------------
use master
drop database curso

CONCLUSÃO

Embora a função Split_string tenha sido introduzida apenas no SQL2016, como você pode ver, há várias alternativas a esse problema. Para mim agrada muito a solução de transformar em XML, pois esse é, sem sobra de dúvidas, o formato mais popular e dinâmico para trabalharmos atualmente!

Espero que você tenha gostado e continue firme e forte com seus estudos!
Abraço do seu amigo Josué 🙂

2 respostas

  1. Bom dia! Tudo bem?

    E se no exemplo tivesse que dividir 3 colunas, ‘João|20|M;Maria|19|F;José|22|M;Oscar|16|M’? Eu deveria incluir outro separador?

    Att,

    Bruno Santos

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *