locked
Converter variável Varchar com números separados por virgula em Int RRS feed

  • Pergunta

  • Boa tarde

    Tenho uma variável Varchar que armazena números separados por virgula.

    Exemplo @varialvel = '1,8,10,2' e adicionar na minha select assim SELECT * FROM [TABLE] WHERE [CAMPO INT] IN (@variavel) 

    Como Converter essa variável Vachar em INT com os números separados por virgula assim  1,8,10,2

    Desde já muito obrigado!

    terça-feira, 29 de novembro de 2016 16:20

Respostas

  • Voce vai ter que implementar uma funçao do tipo Split, como explicado neste artigo:

    http://www.sommarskog.se/arrays-in-sql.html

    Note que o SQL 2016  possui agora (antes tarde do que nunca) uma funçao nativa:

    https://msdn.microsoft.com/en-us/library/mt684588.aspx

    att


    William John Adam Trindade
    Analyste-programmeur
    ----------------------------------------------------------

    • Marcado como Resposta Marcio Camargo terça-feira, 29 de novembro de 2016 16:45
    • Não Marcado como Resposta Marcio Camargo terça-feira, 29 de novembro de 2016 16:51
    • Marcado como Resposta Marcio Camargo quarta-feira, 30 de novembro de 2016 15:58
    terça-feira, 29 de novembro de 2016 16:31
  • Olá,

    Recomendo 2 passos

    1) Criar uma função tabular que consiga fazer o split desses itens baseado em um delimitador. A função pode ser essa:

    CREATE FUNCTION [dbo].[Split] 
    ( 
        @string NVARCHAR(MAX), 
        @delimiter CHAR(1) 
    ) 
    RETURNS @output TABLE(item NVARCHAR(MAX) 
    ) 
    BEGIN 
        DECLARE @start INT, @end INT 
        SELECT @start = 1, @end = CHARINDEX(@delimiter, @string) 
        WHILE @start < LEN(@string) + 1 BEGIN 
            IF @end = 0  
                SET @end = LEN(@string) + 1
           
            INSERT INTO @output (item)  
            VALUES(SUBSTRING(@string, @start, @end - @start)) 
            SET @start = @end + 1 
            SET @end = CHARINDEX(@delimiter, @string, @start)
            
        END 
        RETURN 
    END

    2) Para utilizar na sua consulta e obter o mesmo resultado que deseja, faça assim:

    SELECT * FROM [TABLE] WHERE [CAMPO INT] IN (SELECT CAST(item AS INT) FROM dbo.Split(@variavel, ',')) 


    Valeu!


    Se a resposta for relevante ou tenha resolvido seu problema, marque como útil/resposta!

    André Secco
    Microsoft MSP & MSDN Tech Advisor
    Blog: http://andresecco.com.br
    GitHub: http://github.com/andreluizsecco
    Twitter: @andre_secco


    • Editado André SeccoMVP terça-feira, 29 de novembro de 2016 16:32
    • Marcado como Resposta Marcio Camargo terça-feira, 29 de novembro de 2016 16:46
    terça-feira, 29 de novembro de 2016 16:27
  • Sua funcao foi criada assim:

    RETURNS @output TABLE(splitdata NVARCHAR(MAX) )

    ?

    Att


    William John Adam Trindade
    Analyste-programmeur
    ----------------------------------------------------------

    • Marcado como Resposta Marcio Camargo terça-feira, 29 de novembro de 2016 16:43
    terça-feira, 29 de novembro de 2016 16:37
  • Deleted
    • Marcado como Resposta Marcio Camargo quarta-feira, 30 de novembro de 2016 15:58
    quarta-feira, 30 de novembro de 2016 10:36
  • Boa tarde André Secco,

    Obrigado pelo retorno rapido!

    Tentei criar a sua função e esta dando erro na linha referente a 

    INSERT INTO @output (splitdata) 

    e a mensagem de erro

    Mensagem 207, Nível 16, Estado 1, Procedimento Split, Linha 15
    Invalid column name 'splitdata'.

    Desde já muito obrigado!

    • Marcado como Resposta Marcio Camargo terça-feira, 29 de novembro de 2016 16:43
    terça-feira, 29 de novembro de 2016 16:35

Todas as Respostas

  • Olá,

    Recomendo 2 passos

    1) Criar uma função tabular que consiga fazer o split desses itens baseado em um delimitador. A função pode ser essa:

    CREATE FUNCTION [dbo].[Split] 
    ( 
        @string NVARCHAR(MAX), 
        @delimiter CHAR(1) 
    ) 
    RETURNS @output TABLE(item NVARCHAR(MAX) 
    ) 
    BEGIN 
        DECLARE @start INT, @end INT 
        SELECT @start = 1, @end = CHARINDEX(@delimiter, @string) 
        WHILE @start < LEN(@string) + 1 BEGIN 
            IF @end = 0  
                SET @end = LEN(@string) + 1
           
            INSERT INTO @output (item)  
            VALUES(SUBSTRING(@string, @start, @end - @start)) 
            SET @start = @end + 1 
            SET @end = CHARINDEX(@delimiter, @string, @start)
            
        END 
        RETURN 
    END

    2) Para utilizar na sua consulta e obter o mesmo resultado que deseja, faça assim:

    SELECT * FROM [TABLE] WHERE [CAMPO INT] IN (SELECT CAST(item AS INT) FROM dbo.Split(@variavel, ',')) 


    Valeu!


    Se a resposta for relevante ou tenha resolvido seu problema, marque como útil/resposta!

    André Secco
    Microsoft MSP & MSDN Tech Advisor
    Blog: http://andresecco.com.br
    GitHub: http://github.com/andreluizsecco
    Twitter: @andre_secco


    • Editado André SeccoMVP terça-feira, 29 de novembro de 2016 16:32
    • Marcado como Resposta Marcio Camargo terça-feira, 29 de novembro de 2016 16:46
    terça-feira, 29 de novembro de 2016 16:27
  • Voce vai ter que implementar uma funçao do tipo Split, como explicado neste artigo:

    http://www.sommarskog.se/arrays-in-sql.html

    Note que o SQL 2016  possui agora (antes tarde do que nunca) uma funçao nativa:

    https://msdn.microsoft.com/en-us/library/mt684588.aspx

    att


    William John Adam Trindade
    Analyste-programmeur
    ----------------------------------------------------------

    • Marcado como Resposta Marcio Camargo terça-feira, 29 de novembro de 2016 16:45
    • Não Marcado como Resposta Marcio Camargo terça-feira, 29 de novembro de 2016 16:51
    • Marcado como Resposta Marcio Camargo quarta-feira, 30 de novembro de 2016 15:58
    terça-feira, 29 de novembro de 2016 16:31
  • Boa tarde André Secco,

    Obrigado pelo retorno rapido!

    Tentei criar a sua função e esta dando erro na linha referente a 

    INSERT INTO @output (splitdata) 

    e a mensagem de erro

    Mensagem 207, Nível 16, Estado 1, Procedimento Split, Linha 15
    Invalid column name 'splitdata'.

    Desde já muito obrigado!

    • Marcado como Resposta Marcio Camargo terça-feira, 29 de novembro de 2016 16:43
    terça-feira, 29 de novembro de 2016 16:35
  • Sua funcao foi criada assim:

    RETURNS @output TABLE(splitdata NVARCHAR(MAX) )

    ?

    Att


    William John Adam Trindade
    Analyste-programmeur
    ----------------------------------------------------------

    • Marcado como Resposta Marcio Camargo terça-feira, 29 de novembro de 2016 16:43
    terça-feira, 29 de novembro de 2016 16:37
  • Boa tarde,

    Marcio, segue uma outra alternativa para teste utilizando XML para separar os códigos:

    with CTE_Codigos as
    (
        SELECT 
            O.Codigo
        FROM
        (
             SELECT 
                 cast('<X>' + replace(@variavel, ',', '</X><X>') + '</X>' as XML) as xmlfilter 
        ) F
        CROSS APPLY
        ( 
             SELECT 
                 fdata.D.value('.', 'int') as Codigo
             FROM F.xmlfilter.nodes('X') as fdata(D)
        ) O
    )
    
    select t.* 
    from Tabela as t
    inner join CTE_Codigos as c
        on c.Codigo = t.Codigo
    

    Espero que ajude


    Assinatura: http://www.imoveisemexposicao.com.br

    terça-feira, 29 de novembro de 2016 16:38
  • Era isso mesmo Andre,

    Funcionou perfeitamente!

    Muito Obrigado peloa força!

    terça-feira, 29 de novembro de 2016 16:45
  • Caso tenha usado a soluçao que o André postou, favor dar os créditos para ele.

    Att


    William John Adam Trindade
    Analyste-programmeur
    ----------------------------------------------------------

    terça-feira, 29 de novembro de 2016 16:47
  • Marcio,

    A partir do Microsoft SQL Server 2016 teremos suporte nativo para este de necessidade através do uso da função String_Split


    Pedro Antonio Galvao Junior [MVP | MCC | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]

    terça-feira, 29 de novembro de 2016 17:22
  • Muito bom. 

    Funcionou perfeitamente.

    Obrigado.

    quinta-feira, 16 de maio de 2019 18:47
  • Use desta forma

    (SELECT COUNT(FIELD) FROM TABLE_NAME

    WHERE FIELD2 in (select value from STRING_SPLIT(FIELS_QUE_TEM_STRING, ','))

    ) AS QT_QUANTIDADE


    sexta-feira, 24 de março de 2023 13:40