Fala pessoal!
Um pouco mais de 5 anos após compartilhar com vocês o código da função Split, que permite recuperar uma parte da string quebrada por um delimitador, dessa vez venho compartilhar uma nova função, chamada charindexada, escrita pelo Brunno Araújo e que gentilmente me cedeu os “direitos de copyright” para compartilhá-la aqui no blog.

Interessado em aprender mais sobre split?

Essa função tem o objetivo básico de permitir algumas consultas especializadas utilizando separadores em uma string.

Seus parâmetros são:

  • @delimitador_esquerda: String que representa o delimitador à esquerda da string. Pode-se utilizar o mesmo delimitador no início e fim ou podem ser delimitadores diferentes.
  • @posicao_inicial: Número do delimitador inicial. Especifica a partir de qual parte da string será iniciada a extração do texto.
  • @delimitador_direita: String que representa o delimitador à direita da string. Caso seja diferente do delimitador inicial, poderá extrair o texto que está entre os dois delimitadores. Caso seja igual ao delimitador inicial, pode-se extrair partes da string (meio)
  • @posicao_fim: Número do delimitador final. Especifica quantas partes serão extraídas do texto.
  • @string: A string em si que será analisada e extraída
  • @tipo: Indica o tipo de retorno da função. Tipo = 0 retorna a posição da string localizada. Tipo = 1 (padrão), retorna a string localizada.

Abaixo, vou mostrar alguns exemplos de como ela pode ser útil.

Exemplo 1 – Texto entre delimitadores

No exemplo abaixo, quero retornar a string que está entre os delimitadores “/” e “\”:

DECLARE @String VARCHAR(MAX) = 'Teste da charindexa do /Bruno Arraujo\ aqui no blog'
SELECT dbo.charindexada('/', 1, '\', 1, @String, 1)

Resultado:

Exemplo 2 – Recuperar o início de uma string delimitada

No exemplo abaixo, quero retornar as 3 primeiras partes de uma string delimitada por underline (_):

DECLARE @String VARCHAR(MAX) = 'Teste_da_charindexa_do_/Brunno_Arraujo\_aqui_no_blog_'

SELECT dbo.charindexada('_', 0, '_', 3, @String, 1)

Resultado:

Exemplo 3 – Recuperar o meio de uma string delimitada

No exemplo abaixo, vou mostrar como recuperar 2 partes de uma string delimitada por underline (_), a partir da 4 parte:

DECLARE @String VARCHAR(MAX) = 'Teste_da_charindexa_do_/Bruno_Arraujo\_aqui_no_blog_'

SELECT dbo.charindexada('_', 4, '_', 2, @String, 1)

Resultado:

Exemplo 4 – Recuperar o final de uma string delimitada

No exemplo abaixo, vou mostrar como recuperar o final de uma string (99 partes kkkk) a partir da 4ª parte de uma string delimitada por underline (_):

DECLARE @String VARCHAR(MAX) = 'Teste_da_charindexa_do_/Brunno_Araujo\_aqui_no_blog_'

SELECT dbo.charindexada('_', 4, '_', 99, @String, 1)

Resultado:

Exemplo 5 – Recuperar só uma parte da string delimitada

No exemplo abaixo, vou mostrar como recuperar somente uma parte (4ª parte) de uma string delimitada por ponto-e-virgula (;):

DECLARE @String VARCHAR(MAX) = 'Teste;da;charindexa;do;Brunno;Araujo;aqui;no;blog;'

SELECT dbo.charindexada(';', 4, ';', 1, @String, 1)

Resultado:

Código-fonte da charindexada:

E aqui, vou disponibilizar o código da função charindexada pra você utilizá-las nos seus projetos, estudos e testes:

CREATE FUNCTION [dbo].[charindexada] (    
    @delimitador_esquerda VARCHAR(20) = '',
    @posicao_inicial BIGINT = 0,
    @delimitador_direita VARCHAR(20) = '',  
    @posicao_fim BIGINT = 0,                   
    @string VARCHAR(8000)= '',
    @tipo BIT = 1
)                      
RETURNS VARCHAR(8000) 
AS 
BEGIN

    DECLARE 
        @string_AUX		VARCHAR(8000),
        @CONT_AUX		BIGINT	= 0,
        @CONT_POS_INI	BIGINT	= 0,
        @DELIM_POS_INI	BIGINT	= 0,
        @POSINI_CONT	BIGINT	= 0,
        @CONT_POS_FIM	BIGINT	= 0,
        @DELIM_POS_FIM	BIGINT	= 0,
        @TAM_D_INI		BIGINT,
        @TAM_D_FIM		BIGINT,
        @tipo_FIM		VARCHAR(8000)

    SET @string_AUX = LTRIM(RTRIM(@string))
    SET @TAM_D_INI =  (CASE @delimitador_esquerda WHEN '' THEN 1 ELSE LEN(@delimitador_esquerda) END)
    SET @TAM_D_FIM =  (CASE @delimitador_direita WHEN '' THEN 1 ELSE LEN(@delimitador_direita) END)

-- ############################ CAPTURA DAS POSIÇÕES ############################

    -- ### POSIÇÃO DO 1º DELIMITADOR ###

    WHILE (@CONT_AUX < @posicao_inicial)
    BEGIN

        SET @DELIM_POS_INI	= CHARINDEX(@delimitador_esquerda,@string_AUX,0) 
        SET @string_AUX		= SUBSTRING(@string_AUX,@DELIM_POS_INI+@TAM_D_INI,LEN(@string_AUX))
        SET @CONT_AUX		= @CONT_AUX + 1		
        SET @CONT_POS_INI	= @CONT_POS_INI + @DELIM_POS_INI
    
    END

    SET @CONT_AUX = 0

    -- ### POSIÇÃO DO 2º DELIMITADOR ###

    WHILE (@CONT_AUX < @posicao_fim)
    BEGIN
        
        SET @DELIM_POS_FIM 	= CHARINDEX(@delimitador_direita,@string_AUX) 
        SET @string_AUX    	= SUBSTRING(@string_AUX,@DELIM_POS_FIM+@TAM_D_INI,LEN(@string_AUX))
        SET @CONT_AUX	 	= @CONT_AUX + 1			
        SET @CONT_POS_FIM 	= @CONT_POS_FIM + @DELIM_POS_FIM		
    
    END				

    SET @DELIM_POS_FIM = LEN(SUBSTRING(@string_AUX,0,CHARINDEX(@delimitador_direita,@string_AUX)))				

-- ############################ VALIDAÇÕES ############################

    IF (@tipo = 0 AND @delimitador_esquerda <> '') -- ### POSICAO DO DELIMITADOR ###
    BEGIN
        SELECT @tipo_FIM = @CONT_POS_INI
    END

    IF (@tipo = 1)
    BEGIN
    
        IF (@delimitador_direita = '' AND @posicao_fim = 0) -- ### POS_INI até FINAL ###
            SET @tipo_FIM = SUBSTRING(@string,@CONT_POS_INI+@TAM_D_INI,LEN(@string))
        
        IF (@delimitador_esquerda <> '' AND @delimitador_direita <> '')	-- ### POS_INI até POS_FIM ###
            SET @tipo_FIM = SUBSTRING(@string,@CONT_POS_INI+@TAM_D_INI,@CONT_POS_FIM-1) 
        
        IF (@delimitador_esquerda = '' AND @posicao_inicial = 0) -- ### INICIO até POS_FIM ###
            SET @tipo_FIM = SUBSTRING(@string,0,@CONT_POS_FIM)			
        
    END

    RETURN ISNULL(@tipo_FIM, @tipo)

END

É isso aí, pessoal!
Espero que vocês tenham gostado dessa função bem legal e que promete ajudar bastante as pessoas que tem necessidades parecidas com as que demonstrei aqui no artigo e agradecer novamente ao Brunno Araújo pelo tempo gasto no desenvolvimento dessa função e em ter deixado eu postá-la aqui no blog.

Um grande abraço e até a próxima!