Saltar al contenido

Convertir hexadecimal a varchar

Ya no tienes que indagar más por otros sitios porque has llegado al espacio indicado, tenemos la respuesta que quieres recibir y sin complicaciones.

Solución:

Parece tu varbinary string Me inyectaron algunas tonterías. Todas las secuencias de dos 00 los valores son null personajes, por eso tu string termina con la conversión. El primer personaje es 0x24 (signo de dólar), por lo que la salida es solo un signo de dólar.

SELECT CONVERT(varchar(60), 0x2400....anything....);
-- is equivalent to:
SELECT CONVERT(varchar(60), 0x24);

Ahora, si tomo tu string y quita todo el 00 secuencias:

SELECT CONVERT(VARCHAR(60), 0x248B0189FF32323633393933352D4B434E);

Consigo algo cercano; de nuevo, hay un montón de basura allí, pero el string estás buscando es ahí:

$‹‰ÿ22639935-KCN

Puede ignorar la basura principal simplemente tomando el valor original y realizando RIGHT() contra ella, pero esto supone que la parte importante de la string tiene siempre la misma longitud (no podemos decirle si es true).

SELECT CONVERT(VARCHAR(60),     
       RIGHT(0x24000000008B010000000089FF32323633393933352D4B434E000000, 15));

O usando SUBSTRING, pero esto supone que la basura al comienzo de la string siempre tiene la misma longitud:

SELECT CONVERT(VARCHAR(60), 
       SUBSTRING(0x24000000008B010000000089FF32323633393933352D4B434E000000, 14, 46));

Tampoco podemos decirte por qué esa basura está ahí y si tiene algún significado adicional. Deberá averiguar cómo se codificaron los valores de esta manera en primer lugar. El valor que querías codificado 22639935-KCN, debería haber lucido un poco diferente como varbinary:

SELECT CONVERT(VARBINARY(32), '22639935-KCN');

--------------------------
0x32323633393933352D4B434E

Entonces, nuevamente, deberá investigar un poco para descubrir por qué este valor no se codificó de esta manera. No podemos responder a todo esto porque no diseñamos su sistema ni almacenamos esos valores.

Esto devuelve el valor Estás buscando. Le sugiero encarecidamente que, si tiene algún control sobre este proceso, deje de almacenar datos en este formato.

DECLARE @hexstr nvarchar(40) = '0x' + SUBSTRING(CONVERT(NVARCHAR(100), 0x008B010000000089FF32323633393933352D4B434E000000, 1),21, 24);
declare @ind int, @byte1 int, @byte2 int, @binvalue varbinary(20)

set @binvalue = 0x

if lower(substring(@hexstr, 1, 2)) = '0x'
    set @ind = 3
else
    set @ind = 1

while ( @ind <= len(@hexstr) )
begin            
    set @byte1 = ascii(substring(@hexstr, @ind, 1))
    set @byte2 = ascii(substring(@hexstr, @ind + 1, 1))
    set @binvalue = @binvalue + convert(binary(1), 
              case 
                    when @byte1 between 48 and 57 then @byte1 - 48  
                    when @byte1 between 65 and 70 then @byte1 - 55  
                    when @byte1 between 97 and 102 then @byte1 - 87 
                    else null end * 16 +
              case 
                    when @byte2 between 48 and 57 then @byte2 - 48  
                    when @byte2 between 65 and 70 then @byte2 - 55  
                    when @byte2 between 97 and 122 then @byte2 - 87 
                    else null end) 
    set @ind = @ind + 2 
end 

SELECT CONVERT(VARCHAR(50), @binvalue)

ingrese la descripción de la imagen aquí

Para envolver esto en una función que devuelva una tabla (la denominada función con valores de tabla), puede hacer algo como:

IF COALESCE(OBJECT_ID('dbo.GetProductCodeFromVARBINARY'), 0) <> 0
BEGIN
    DROP FUNCTION dbo.GetProductCodeFromVARBINARY;
END
GO
CREATE FUNCTION GetProductCodeFromVARBINARY
(
    @Bin VARBINARY(64)
)
RETURNS @VarResults TABLE
(
    ProductCode VARCHAR(50) NULL
)
AS
BEGIN
    DECLARE @hexstr nvarchar(40) = '0x' + SUBSTRING(CONVERT(NVARCHAR(100), @Bin, 1),21, 24);
    declare @ind int, @byte1 int, @byte2 int, @binvalue varbinary(20)

    set @binvalue = 0x

    if lower(substring(@hexstr, 1, 2)) = '0x'
        set @ind = 3
    else
        set @ind = 1

    while ( @ind <= len(@hexstr) )
    begin            
        set @byte1 = ascii(substring(@hexstr, @ind, 1))
        set @byte2 = ascii(substring(@hexstr, @ind + 1, 1))
        set @binvalue = @binvalue + convert(binary(1), 
                  case 
                        when @byte1 between 48 and 57 then @byte1 - 48  
                        when @byte1 between 65 and 70 then @byte1 - 55  
                        when @byte1 between 97 and 102 then @byte1 - 87 
                        else null end * 16 +
                  case 
                        when @byte2 between 48 and 57 then @byte2 - 48  
                        when @byte2 between 65 and 70 then @byte2 - 55  
                        when @byte2 between 97 and 122 then @byte2 - 87 
                        else null end) 
        set @ind = @ind + 2 
    end 

    INSERT INTO @VarResults (ProductCode)
    VALUES (CONVERT(VARCHAR(50), @binvalue));

    RETURN;
END

Para ejecutar esto, puede hacer:

SELECT *
FROM dbo.GetProductCodeFromVARBINARY(0x008B010000000089FF32323633393933352D4B434E000000);

que devuelve esto:

ingrese la descripción de la imagen aquí

O, si es necesario JOIN esto a otra tabla que contenga los valores VARBINARY, puede hacer esto:

CREATE TABLE dbo.VarBinValues
(
    ProdCode VARBINARY(64) NULL
);

INSERT INTO dbo.VarBinValues (ProdCode)
VALUES (0x008B010000000089FF32323633393933352D4B434E000000);

SELECT vbv.ProdCode
    , pc.ProductCode
FROM dbo.VarBinValues vbv
CROSS APPLY dbo.GetProductCodeFromVARBINARY(vbv.ProdCode) pc

Resultados:

ingrese la descripción de la imagen aquí

Si para ti ha resultado provechoso este artículo, sería de mucha ayuda si lo compartes con otros desarrolladores de esta forma contrubuyes a extender nuestro contenido.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *