Transformando um Conjunto de Números Inteiros separados por Vírgulas em Linhas no SQL Server

Pessoal, boa tarde.

Tudo bem? Aproveitando a aproximação do Natal, quero desejar a todos os meus amigos, visitantes, seguidores, enfim á todos que por algum motivo consumam visitar o meu Blog.

UM FELIZ 2012, com muito Amor, Esperança, Paz e principalmente Harmonia.

_______________________________________________________________________

Bom como todos devem estar em clima de festa, não vou ser muito chato e querer compartilhar com vocês algo que possa consumir muito do seu tempo preciso, sendo assim, escolhi um tema bastante prático e que normalmente é muito procurado e questionado nos Fóruns MSDN e TechNet.

Estou me referindo à possibilidade de Separar, Dividir, Desagrupar ou simplesmente Fatiar um conjunto de Números Inteiros separados por Vírgulas no SQL Server. Este conjunto de números pode ser reconhecido ou definido como um Array Simples, Uma coleção de números, enfim, podemos empregar diversas terminologias, que todas poderão ser bem compreendidas para esta situação.


Vamos lá!

Uma das maiores dificuldades para qualquer Programador, Desenvolver, Analista e até mesmo DBA esta relacionada à forma de tratamento de todo e qualquer dado que se pretende armazenar em uma estrutura de dados do tipo tabela, ou até mesmo a manipulação deste dado.

Quando trabalhamos como uma série de valores numéricos temos diversas possibilidades de utilização de recursos específicos para estes valores, como por exemplo:

  • Realização de Cálculos;
  • Utilização de Mecanismos de Pesquisa e Ordenação de Valores;
  • Métodos para organização e diferenciação de dados; entre outros.

Até ai tudo bem, trabalhar diretamente com valores inteiros, números, fórmulas é algo que já realizamos há muito tempo. Agora se por acaso em um dos nossos Aplicativos, Sistemas ou até mesmo Algoritmos nos deparamos com um conjunto de 5, 10, 20, 100, 500 números armazenados em uma estrutura de dados de forma seqüência ou não, mas todos os números separados por vírgula. Então o que fazer ou como fazer para trabalhar de forma individual este conjunto?

É justamente esta pergunta que eu pretender responder para você. Como podemos manipular um conjunto de números inteiros, contidas nesta estrutura, reconhecendo cada número de forma individual e posteriormente separando este conjunto em valores independentes.

Para tentar responder este questionamento, bem como, demonstrar as possibilidades, vou começar a explicar cada uma das partes do Código 1, apresentado abaixo:

— Código 1 —

Declare @Resultado Table (Numero Int)

Declare @ListaValores VarChar(50), @PosicaoAtual Int            

Set @ListaValores=’25,3545,45,6015,2569,14535,2544,4878,15′

While CharIndex(‘,’,@ListaValores,0) <> 0

 Begin

  Set @PosicaoAtual = SubString(@ListaValores,1,CharIndex(‘,’,@ListaValores,0)-1)

  Set @ListaValores = SubString(@ListaValores,CharIndex(‘,’,@ListaValores,0)+1,Len(@ListaValores))

  If Len(@PosicaoAtual) > 0

    Insert Into @Resultado Values (Convert(Int, @PosicaoAtual))   

 End

  If Len(@ListaValores) > 0

    Insert Into @Resultado Values (Convert(Int,@ListaValores))

Select * from @Resultado

Começamos a análise e entendimento do Código 1, com base nas linhas 1,2 e 3 definida como Código 1 – Parte 1, apresentada a seguir:

— Código 1 – Parte 1 —

1. Declare @Resultado Table (Numero Int)

2. Declare @ListaValores VarChar(50), @PosicaoAtual Int            

3. Set @ListaValores=’25,3545,45,6015,2569,14535,2544,4878,15′

Na linha de número 1, estou fazendo a declaração de uma estrutura de armazenamento de valores, sendo esta estrutura denominada @Resultado, o que representa uma variável do Tipo Tabela, existente somente durante a execução completa do Código 1.

A linha de número 2, estou declarando duas variáveis denominadas:

  • @ListaValores: Utilizada como Array ou Container para armazenamento do conjunto de valores numéricos; e
  • @PosicaoAtual: Utilizada para armazenar durante a execução do Código 1, o primeiro valor existente dentro do Array.

Para a linha de número 3, estou atribuindo para a variável @ListaValores este conjunto de números: ‘25,3545,45,6015,2569,14535,2544,4878,15’. Observe que todos os valores estão sendo separados por vírgulas.

Agora que já conhecemos a Parte 1 do nosso Código 1, vou destacar a Parte 2 que representa as seguintes linhas:

— Codigo 1 – Parte 2 —

4. While CharIndex(‘,’,@ListaValores,0) <> 0

5. Begin

6.  Set @PosicaoAtual = SubString(@ListaValores,1,CharIndex(‘,’,@ListaValores,0)-1)

7.  Set @ListaValores = SubString(@ListaValores,CharIndex(‘,’,@ListaValores,0)+1,Len(@ListaValores))

8.  If Len(@PosicaoAtual) > 0

9.   Insert Into @Resultado Values (Convert(Int, @PosicaoAtual))   

10. End

A linha de número 4, apresenta o comando While utilizado para criar e manter a estrutura de repetição enquanto a condição CharIndex(‘,’,@ListaValores,0) for diferente de Zero.

As linhas de número 5 e 10, são de conhecimento de todos, responsáveis em iniciar e encerrar o bloco de código do comando While.

Um dos segredos do Código 1, encontra-se nas linhas de número 6 e 7, onde estamos fazendo as seguintes operações:

  • Na linha 6: É realizado um tratamento para obter o primeiro valor númerico dentro deste conjunto, através da função Substring() dividida em 3 parâmetros:
    • Parâmetro 1 – Informamos a String que contem os valores que queremos obter uma determinada posição, neste caso, utilizamos a variável @ListaValores;
    • Parâmetro 2 – Neste parâmetro devemos informar a posição e número Inteiro que o SQL Server deve começar se posicionar para capturar a porção de dados desejada.

Como nossos números estão armazenados na mesma estrutura o que dificulta em muito a identificação dos valores, é necessário utilizar a função string CharIndex, responsável em encontrar um determinado caracter do tipo String dentro de uma String definida pelo usuário, que neste caso será a Vírgula(‘,’) dentro da variável @ListaValores. 

    • Parâmetro 3 – Neste parâmetro devemos informar o tamanho da porção ou parte de dados string que queremos copiar. Neste parâmetro esta sendo passado um valor fixo -1, pois como o segundo parâmetro vai retornar a posição do dado a ser copia incluíndo a vírgula, temos que desconsiderar justamente a vírgula na cópia.
  • Após a realização deste tratamento o resultado é armazenado dentro da variável @PosicaoAtual.

A linha de número 7, apresenta o outro segredo do Código 1, realizando um tratamento similar a linha de número 6, mas com algumas diferenças.

Ao invês de armazenarmos o resultado do tramanento de valores na variável @PosicaoAtual, estamos na verdade, substituíndo o conteúdo da variável @ListaValores, removendo sempre valor contido da variável @PosicaoAtual, conforme o bloco While vai se executado.

A Figura 1 apresentada a seguir ilustra como o SQL Server vai realizando o armazenamento dos dados na variável @PosicaoInicial, removendo este mesmo valor da variável @ListaValores.

Figura 1, Valores armazenados nas variáveis @PosicaoAtual e @ListaValores.

Além disso, temos outras duas diferença nos parâmetros de número 2 e 3 da função Substring(), onde: 

    • Parâmetro 2 – Ao invês de realizarmos a diminuição de uma posição conforme apresentado na linha 6, estamos fazendo justamento o contrário, acrescentando mais linha posição no valor retornado pelo CharIndex, incluíndo então a posição da Vírgula.
    • Parâmetro 3 – Neste parâmetro estamos passando o tamanho total da nossa variável @ListaValores.

Após os tratamentos realizados nas linhas 6 e 7, é realizado uma análise condicional na linha 8, responsável em verificar se a variável @PosicaoAtual possui algum valor, caso esta condição seja verdadeiro o valor contido nesta variável é armazenada na variável table @Resultado, através do comando Insert.

Para finalizar vou apresentar a parte final do Código 1, com base nas seguintes linhas:

— Codigo 1 – Parte Final —

11. If Len(@ListaValores) > 0

12. Insert Into @Resultado Values (Convert(Int,@ListaValores))

13. Select * from @Resultado

Na linha de número 11, estamos realizando uma nova análise condicional, responsável em verificar se a variável @ListaValores, possui algum valor, sendo este valor o último valor existente dentro do conjunto de valores declarados, posteriormente armazenado na tabela @Resultado, conforme a apresenta a linha de número 12.

A linha de número 13, tem como finalidade apresentar o resultado da seperação deste conjunto de valores numéricos, conforme apresenta a Figura 2.

Figura 2 – Conjunto de números separados em linhas.

Galera, é isso ai, vou chegando ao final de mais uma dica, espero que todos possam ter gostado, que as informações apresentadas aqui possam ajudar no seu dia-á-dia.

Nos encontramos em breve.

Até mais.

Anúncios

Sobre Junior Galvão - MVP

Profissional com vasta experiência na área de Tecnologia da Informação e soluções Microsoft. Graduado no Curso Superior em Gestão da Tecnologia de Sistemas de Informação. Pós-Graduado no Curso de Gestão e Engenharia de Processos para Desenvolvimento de Software com RUP na Faculdade FIAP - Faculdade de Informática e Administração Paulista de São Paulo. Pós-Graduado em Gestão da Tecnologia da Informação Faculdade - ESAMC Sorocaba. Formação MCDBA Microsoft, autor de artigos acadêmicos e profissionais postados em Revistas, Instituições de Ensino e WebSistes. Meu primeiro contato com tecnologia ocorreu em 1995 após meus pais comprarem nosso primeiro computador, ano em que as portas para este fantástico mundo se abriram. Neste mesmo ano, comecei o de Processamento de Dados, naquele momento a palavra TI não existia, na verdade a Tecnologia da Informação era conhecida como Computação ou Informática, foi assim que tudo começou e desde então não parei mais, continuando nesta longa estrada até hoje. Desde 2001 tenho atuado como Database Administrator - Administrador de Banco de Dados - SQL Server em tarefas de Administração, Gerenciamento, Migração de Servidores e Bancos de Dados, Estratégias de Backup/Restauração, Replicação, LogShipping, Implantação de ERPs que utilizam bancos SQL Server, Desenvolvimento de Funções, Stored Procedure, Triggers. Experiência na Coordenação de Projetos de Alta Disponibilidade de Dados, utilizando Database Mirroring, Replicação Transacional e Merge, Log Shipping. Atualmente trabalho como Administrador de Banco de Dados no FIT - Instituto de Tecnologia da Flextronics, como também, Consultor em Projetos de Tunnig e Performance para clientes, bem como, Professor Titular na Fatec São Roque. Desde 2008 exerço a função de Professor Universitário, para as disciplinas de Banco de Dados, Administração, Modelagem de Banco de Dados, Programação em Banco de Dados, Sistemas Operacionais, Análise e Projetos de Sistemas, entre outras. Possuo titulações e Reconhecimentos: Microsoft MVP, MCC, MSTC e MIE.
Esse post foi publicado em Dicas, Mundo SQL Server, Scripts, SQL Server, VIRTUAL PASS BR e marcado , , , . Guardar link permanente.

4 respostas para Transformando um Conjunto de Números Inteiros separados por Vírgulas em Linhas no SQL Server

  1. priscila disse:

    Meu amigo!, Você me ajudou muito a esclarecer sobre isso!..
    valeu..

    Só uma pergunta: cada resultado retornado deverá ser inserido no select, isso acontece porque a memória não consegue armazenar os valores, tipo a orientação a objeto, na qual eu tenho uma lista que armazena os valores inseridos.
    como a memória do banco trata isso, pelo que eu percebi não existe isso por isso é necessário guardar as informações em uma tabela temporária e depois pegar os valores.

    obrigada!

    Curtir

    • Priscila, boa tarde.

      Quero agradecer a sua visita e comentário, vou tentar responder a sua dúvida.

      Todo e qualquer SGBD, possui memória e memória auxiliar, como também áreas de processamento temporário.

      Neste exemplo estou fazendo armazenamento dos dados diretamente nas tabelas por se tratar de um processo que pode ocupar de uma forma bastante volátil uma determinada área de memória, o que muitas vezes pode representar um aumento no tempo de processamento.

      Além disso, como estou realizando uma separação de valores, como se os mesmos estivessem armazenados em um array, isso é outro indicar para fazer o armazenado dos dados em disco para conseguirmos ter esta distribuição de dados, sem necessitarmos utilizar qualquer tipo de ponteiro em memória para identificar e encontrar a informação.

      Até mais.

      Curtir

  2. Cara mto bom!!! Me ajudou mtooooooooooooooooooo Obrigado

    Curtir

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s