none
Como pegar palavra por palavra de uma linha. RRS feed

  • Pergunta

  • Boa noite, colegas.

    Alguém tem alguma dica de como posso pegar  uma linha do banco e inserir em outra tabela palavra por palavra?

    Exemplo

    select top 1 frase from texto

    Retorno: O direito de propriedade é constitucionalmente garantido, devendo as propriedades atender a sua função social.

    Então: inserir esse retorno na tabela palavras:

    select * from palavras

    O
    direito
    de
    propriedade
    é
    constitucionalmente
    garantido
    devendo
    as
    propriedades
    atender
    a
    sua
    função
    social

    Estou fazendo com um loop com charindex procurando espaço. Mas deve ter algo mais simples de fazer. Pois, como é muito texto fico tento de fazer várias correções.

    Abraço

    declare @enunciado varchar(8000)
    declare @palavra varchar(8000)
    declare @ultimaPalavra varchar(8000)
    declare @inicio int
    declare @tamanhoEnunciado int
    
    
    select @enunciado = texto from teste
    select @ultimaPalavra =reverse(substring(reverse(@enunciado),0,charindex(' ',reverse(@enunciado))))
    select @inicio =0
    
    
    while (LEN(@enunciado)!=0)
    begin
    if ((charindex(' ',@enunciado))=0)
    begin
    print @enunciado
    break;
    end
    else
    begin
    select @inicio = charindex(' ',@enunciado)+1
    select @palavra = SUBSTRING(@enunciado,0,@inicio)
    select @enunciado=substring(@enunciado,@inicio,9999999)
    print @palavra
    end
    end
    


    • Editado Marcelo Diegues segunda-feira, 3 de agosto de 2020 07:38 inserir codigo sql
    segunda-feira, 3 de agosto de 2020 06:59

Respostas

  • Bom dia,

    Se você estiver utilizando o SQL Server 2016 ou mais recente pode utilizar a função nativa String_Split. Ex:

    with CTE_Top as
    (
        select top 1 frase from texto
    )
    
    select Value
    from CTE_Top
    cross apply STRING_SPLIT(frase, ' ')
    

    Espero que ajude


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

    • Marcado como Resposta Marcelo Diegues segunda-feira, 3 de agosto de 2020 15:15
    segunda-feira, 3 de agosto de 2020 12:35
  • Marcelo,

    Sem problemas, a cada nova versão o SQL Serve esta evoluindo mais ainda.

    Gostaria de compartilhar outras abordagens que também podem lhe ajudar:

    -- Utilizando a tabela spt_values para realizar o Split de palavras --
    DECLARE @var VARCHAR(100)
    SET @var = 'Conhecendo, cada, vez, mais, os segredos, do SQL Server.....' 
    
    SELECT
    	SUBSTRING	(',' + @var + ',',Number + 1,CHARINDEX	(',',',' + @var + ',',Number + 1	) - Number - 1) as value
    FROM master..spt_values
    WHERE Number >= 1
    AND Number < LEN(',' + @var + ',') - 1
    AND SUBSTRING(',' + @var + ',', Number, 1) = ','
    AND type = 'P'
    ORDER BY Number
    Go

    -- Criando uma CTE para realizar o Split de palavras --
    DECLARE @s VARCHAR(8000), @d VARCHAR(10)
    SET @s = 'separar por espaço em branco'
    SET @d = ' ' 
    
    ;WITH split(i,j) AS
    (
    SELECT i = 1, j = CHARINDEX(@d, @s + @d)
    UNION ALL
    SELECT i = j + 1, j = CHARINDEX(@d, @s + @d, j + 1) FROM split
       WHERE CHARINDEX(@d, @s + @d, j + 1) <> 0
    )
    SELECT SUBSTRING(@s,i,j-i)
    FROM split
    Go

    -- Função Split em Múltiplas Colunas --
    CREATE FUNCTION dbo.UFN_SEPARATES_COLUMNS(@TEXT1 varchar(8000), @COLUMN tinyint, @SEPARATOR char(1))
    RETURNS varchar(8000)
    AS
      BEGIN
           DECLARE @POS_START  int = 1
           DECLARE @POS_END    int = CHARINDEX(@SEPARATOR, @TEXT, @POS_START)
    
           WHILE (@COLUMN >1 AND @POS_END> 0)
             BEGIN
                 SET @POS_START = @POS_END + 1
                 SET @POS_END = CHARINDEX(@SEPARATOR, @TEXT, @POS_START)
                 SET @COLUMN = @COLUMN - 1
             END 
    
           IF @COLUMN > 1  SET @POS_START = LEN(@TEXT) + 1
           IF @POS_END = 0 SET @POS_END = LEN(@TEXT) + 1 
    
           RETURN SUBSTRING (@TEXT, @POS_START, @POS_END - @POS_START)
      END
    GO
    
    SELECT
      dbo.UFN_SEPARATES_COLUMNS(@ISBN, 1, '-') AS PREFIX,
      dbo.UFN_SEPARATES_COLUMNS(@ISBN, 2, '-') AS REGISTRATION_GROUP,
      dbo.UFN_SEPARATES_COLUMNS(@ISBN, 3, '-') AS REGISTRANT,
      dbo.UFN_SEPARATES_COLUMNS(@ISBN, 4, '-') AS PUBLICATION,
      dbo.UFN_SEPARATES_COLUMNS(@ISBN, 5, '-') AS [CHECK]
    GO

    -- Realizando Split em uma Variável Table --
    CREATE TABLE tabela (ID int, VALOR varchar(200))
    Go
    
    INSERT into tabela values 
      (1111,'A1, A2, A3  '), (2222,'B1'), (3333, ' C1,  C2,  C3,C4')
    Go
    
    CREATE TABLE nova_tabela (ID int, VALOR varchar(30));
    Go
    
    -- Cria a Tabela Auxiliar de números --
    set NoCount on
    
    Declare @Nums table (N int)
    Declare @I int
    
    Set @I= 0
    
    While @I <= 200
     begin
      INSERT into @Nums values (@I)
      set @I+= 1
     end
    
    --INSERT into nova_tabela (ID, VALOR) --
      SELECT T1.ID, ltrim(rtrim(SubString(T1.VALOR, N, CharIndex(',', T1.VALOR + ',', N) - N)))
        from tabela as T1  inner join  @Nums 
             on N <= DataLength(T1.VALOR) + 1
                and SubString(',' + T1.VALOR, N, 1) = ','
    Go

    -- Realizando o Split de valores separados por vírgula --
    CREATE FUNCTION SplitID (@IDString VARCHAR(1000))
    RETURNS @IDs TABLE (ID INT)
    AS
    BEGIN
     DECLARE @Position int
    
     WHILE len(@IDString) > 0
       BEGIN
         SET @Position = charindex(',', @IDString)
    
         IF @Position > 0
           begiN
             INSERT @IDs
             SELECT CONVERT(INT, LEFT(@IDString, @Position - 1))
             SET @IDString = RIGHT(@IDString, LEN(@IDString) - @Position)
           END
         ELSE
           BEGIN
             INSERT @IDs
             SELECT CONVERT(INT, @IDString)
             SET @IDString = ''
           END
       END
    RETURN
    END 
    
    
    DECLARE @EmpresaIDs VARCHAR(2000)
    SET @EmpresaIDs = '1, 2, 3, 4, 5'
    
    SELECT E.* FROM Empresas E
    INNER JOIN SplitIDString(@EmpresaIDs) I
    ON E.Empresa = I.ID 
    Go


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | MTAC | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]

    • Marcado como Resposta Marcelo Diegues quinta-feira, 6 de agosto de 2020 16:02
    terça-feira, 4 de agosto de 2020 12:12

Todas as Respostas

  • Bom dia,

    Se você estiver utilizando o SQL Server 2016 ou mais recente pode utilizar a função nativa String_Split. Ex:

    with CTE_Top as
    (
        select top 1 frase from texto
    )
    
    select Value
    from CTE_Top
    cross apply STRING_SPLIT(frase, ' ')
    

    Espero que ajude


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

    • Marcado como Resposta Marcelo Diegues segunda-feira, 3 de agosto de 2020 15:15
    segunda-feira, 3 de agosto de 2020 12:35
  • Nosssaaaaaaaaaaa. Parei no Sql server 2008 :D. Muito bom a resposta, valeu.
    segunda-feira, 3 de agosto de 2020 15:16
  • Marcelo,

    Sem problemas, a cada nova versão o SQL Serve esta evoluindo mais ainda.

    Gostaria de compartilhar outras abordagens que também podem lhe ajudar:

    -- Utilizando a tabela spt_values para realizar o Split de palavras --
    DECLARE @var VARCHAR(100)
    SET @var = 'Conhecendo, cada, vez, mais, os segredos, do SQL Server.....' 
    
    SELECT
    	SUBSTRING	(',' + @var + ',',Number + 1,CHARINDEX	(',',',' + @var + ',',Number + 1	) - Number - 1) as value
    FROM master..spt_values
    WHERE Number >= 1
    AND Number < LEN(',' + @var + ',') - 1
    AND SUBSTRING(',' + @var + ',', Number, 1) = ','
    AND type = 'P'
    ORDER BY Number
    Go

    -- Criando uma CTE para realizar o Split de palavras --
    DECLARE @s VARCHAR(8000), @d VARCHAR(10)
    SET @s = 'separar por espaço em branco'
    SET @d = ' ' 
    
    ;WITH split(i,j) AS
    (
    SELECT i = 1, j = CHARINDEX(@d, @s + @d)
    UNION ALL
    SELECT i = j + 1, j = CHARINDEX(@d, @s + @d, j + 1) FROM split
       WHERE CHARINDEX(@d, @s + @d, j + 1) <> 0
    )
    SELECT SUBSTRING(@s,i,j-i)
    FROM split
    Go

    -- Função Split em Múltiplas Colunas --
    CREATE FUNCTION dbo.UFN_SEPARATES_COLUMNS(@TEXT1 varchar(8000), @COLUMN tinyint, @SEPARATOR char(1))
    RETURNS varchar(8000)
    AS
      BEGIN
           DECLARE @POS_START  int = 1
           DECLARE @POS_END    int = CHARINDEX(@SEPARATOR, @TEXT, @POS_START)
    
           WHILE (@COLUMN >1 AND @POS_END> 0)
             BEGIN
                 SET @POS_START = @POS_END + 1
                 SET @POS_END = CHARINDEX(@SEPARATOR, @TEXT, @POS_START)
                 SET @COLUMN = @COLUMN - 1
             END 
    
           IF @COLUMN > 1  SET @POS_START = LEN(@TEXT) + 1
           IF @POS_END = 0 SET @POS_END = LEN(@TEXT) + 1 
    
           RETURN SUBSTRING (@TEXT, @POS_START, @POS_END - @POS_START)
      END
    GO
    
    SELECT
      dbo.UFN_SEPARATES_COLUMNS(@ISBN, 1, '-') AS PREFIX,
      dbo.UFN_SEPARATES_COLUMNS(@ISBN, 2, '-') AS REGISTRATION_GROUP,
      dbo.UFN_SEPARATES_COLUMNS(@ISBN, 3, '-') AS REGISTRANT,
      dbo.UFN_SEPARATES_COLUMNS(@ISBN, 4, '-') AS PUBLICATION,
      dbo.UFN_SEPARATES_COLUMNS(@ISBN, 5, '-') AS [CHECK]
    GO

    -- Realizando Split em uma Variável Table --
    CREATE TABLE tabela (ID int, VALOR varchar(200))
    Go
    
    INSERT into tabela values 
      (1111,'A1, A2, A3  '), (2222,'B1'), (3333, ' C1,  C2,  C3,C4')
    Go
    
    CREATE TABLE nova_tabela (ID int, VALOR varchar(30));
    Go
    
    -- Cria a Tabela Auxiliar de números --
    set NoCount on
    
    Declare @Nums table (N int)
    Declare @I int
    
    Set @I= 0
    
    While @I <= 200
     begin
      INSERT into @Nums values (@I)
      set @I+= 1
     end
    
    --INSERT into nova_tabela (ID, VALOR) --
      SELECT T1.ID, ltrim(rtrim(SubString(T1.VALOR, N, CharIndex(',', T1.VALOR + ',', N) - N)))
        from tabela as T1  inner join  @Nums 
             on N <= DataLength(T1.VALOR) + 1
                and SubString(',' + T1.VALOR, N, 1) = ','
    Go

    -- Realizando o Split de valores separados por vírgula --
    CREATE FUNCTION SplitID (@IDString VARCHAR(1000))
    RETURNS @IDs TABLE (ID INT)
    AS
    BEGIN
     DECLARE @Position int
    
     WHILE len(@IDString) > 0
       BEGIN
         SET @Position = charindex(',', @IDString)
    
         IF @Position > 0
           begiN
             INSERT @IDs
             SELECT CONVERT(INT, LEFT(@IDString, @Position - 1))
             SET @IDString = RIGHT(@IDString, LEN(@IDString) - @Position)
           END
         ELSE
           BEGIN
             INSERT @IDs
             SELECT CONVERT(INT, @IDString)
             SET @IDString = ''
           END
       END
    RETURN
    END 
    
    
    DECLARE @EmpresaIDs VARCHAR(2000)
    SET @EmpresaIDs = '1, 2, 3, 4, 5'
    
    SELECT E.* FROM Empresas E
    INNER JOIN SplitIDString(@EmpresaIDs) I
    ON E.Empresa = I.ID 
    Go


    Pedro Antonio Galvão Junior [MVP | MCC | MSTC | MIE | MTAC | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados Relacional e Data Warehouse | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]

    • Marcado como Resposta Marcelo Diegues quinta-feira, 6 de agosto de 2020 16:02
    terça-feira, 4 de agosto de 2020 12:12