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 cursoCONCLUSÃ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é 🙂
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
Oi Bruno, exato. O código que gera as colunas também terá de ser alterado… abs Josué