¡Hola, chicos!
Un poco más de 5 años después de compartir contigo el código de función Dividir, que permite recuperar una parte de la cadena rota por un delimitador, en esta ocasión les comparto una nueva función, llamada charindexada, escrita por Brunno Araújo y quien amablemente me dio los “derechos de autor” para compartirlo aquí en el blog.

¿Interesado en aprender más sobre las divisiones?

Esta función tiene el objetivo básico de permitir algunas consultas especializadas utilizando separadores en una cadena.

Sus parámetros son:

  • @delimitador_left: Cadena que representa el delimitador izquierdo de la cadena. Puede utilizar el mismo delimitador al principio y al final o pueden ser delimitadores diferentes.
  • @posicao_inicial: Número delimitador inicial. Especifica desde qué parte de la cadena comenzará la extracción de texto.
  • @delimitador_right: Cadena que representa el delimitador derecho de la cadena. Si es diferente del delimitador inicial, puede extraer el texto que está entre los dos delimitadores. Si es igual al delimitador inicial, puede extraer partes de la cadena (en el medio)
  • @posicao_fim: Número del delimitador final. Especifica cuántas partes se extraerán del texto.
  • @cadena: La cadena en sí que será analizada y extraída.
  • @tipo: Indica el tipo de retorno de la función. Type = 0 devuelve la posición de la cadena localizada. Tipo = 1 (predeterminado), devuelve la cadena localizada.

A continuación, mostraré algunos ejemplos de cómo puede resultar útil.

Ejemplo 1: texto entre delimitadores

En el siguiente ejemplo, quiero devolver la cadena que se encuentra entre los delimitadores "/" y "\":

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

Resultado:

Ejemplo 2: recuperar el comienzo de una cadena delimitada

En el siguiente ejemplo, quiero devolver las primeras 3 partes de una cadena delimitada por un guión bajo (_):

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

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

Resultado:

Ejemplo 3: recuperar la mitad de una cadena delimitada

En el siguiente ejemplo, mostraré cómo recuperar 2 partes de una cadena delimitada por un guión bajo (_), comenzando desde la cuarta parte:

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

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

Resultado:

Ejemplo 4: recuperar el final de una cadena delimitada

En el siguiente ejemplo, mostraré cómo recuperar el final de una cadena (99 partes jajaja) de la cuarta parte de una cadena delimitada por un guión bajo (_):

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

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

Resultado:

Ejemplo 5: recuperar solo parte de la cadena delimitada

En el siguiente ejemplo, mostraré cómo recuperar solo una parte (cuarta parte) de una cadena delimitada por un punto y coma (;):

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

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

Resultado:

Código fuente de caracteres indexados:

Y aquí, pondré a tu disposición el código de la función charindexed para que lo utilices en tus proyectos, estudios y pruebas:

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

¡Eso es todo, amigos!
Espero que hayan disfrutado de esta función realmente interesante y promete ayudar realmente a las personas que tienen necesidades similares a las que demostré aquí en el artículo y gracias nuevamente a Brunno Araújo por el tiempo dedicado a desarrollar esta función y permitirme publicarla aquí en el blog.

¡Un abrazo grande y hasta la próxima!