it-swarm.com.de

Wandle hexadezimal in varchar um

Ich habe eine Spalte mit Werten, die hexadezimal gespeichert sind.

Wenn ich diese Abfrage ausführe:

select column from  table
where column like '%22639935-KCN%';

Dies ist die Ausgabe, die ich bekomme:

0x24000000008B010000000089FF32323633393933352D4B434E000000

Ich möchte den Ausgang in einen Varchar verwandeln. Dies sollte mir einen Wert geben, der dem ähnelt, was in der ähnlichen Aussage steht.

Meine bisherigen Versuche waren:

SELECT CONVERT(VARCHAR(MAX), 
       0x24000000008B010000000089FF32323633393933352D4B434E000000)


SELECT CONVERT(VARCHAR(MAX), CONVERT(VARBINARY(MAX), 
       '0x24000000008B010000000089FF32323633393933352D4B434E000000', 2))

Ich bekomme jedoch folgendes Ergebnis:

$

Wie kann ich diesen Hexadezimalwert in einen Varchar umwandeln?

4
Blue Moon

Es sieht so aus, als ob Ihre Varbinary-Saite mit etwas Unsinn bespritzt wurde. Alle Sequenzen von zwei 00 - Werten sind Nullzeichen. Aus diesem Grund wird Ihre Zeichenfolge bei der Konvertierung beendet. Das erste Zeichen ist 0x24 (Dollarzeichen), weshalb die Ausgabe nur ein Dollarzeichen ist.

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

Wenn ich nun Ihren String nehme und alle 00 - Sequenzen entferne:

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

Ich bekomme etwas in die Nähe; wieder gibt es eine Menge Müll drin, aber die Zeichenfolge, nach der Sie suchen ist drin:

$‹‰ÿ22639935-KCN

Sie können den führenden Müll ignorieren, indem Sie einfach den ursprünglichen Wert nehmen und RIGHT() dagegen ausführen. Dies setzt jedoch voraus, dass der wichtige Teil der Zeichenfolge immer dieselbe Länge hat (wir können Ihnen nicht sagen, ob dies der Fall ist). .

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

Oder mit SUBSTRING, aber dies setzt voraus, dass der Müll am Anfang der Zeichenfolge immer dieselbe Länge hat:

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

Wir können Ihnen auch unmöglich sagen warum, dass Müll da ist und ob er eine zusätzliche Bedeutung hat. Sie müssen zunächst herausfinden, wie die Werte auf diese Weise codiert wurden. Der Wert, den Sie codieren möchten, 22639935-KCN, Sollte etwas anders aussehen als varbinary:

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

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

Sie müssen also erneut einige Nachforschungen anstellen, um herauszufinden, warum dieser Wert nicht auf diese Weise codiert wurde. Wir können all dies nicht beantworten, da wir Ihr System nicht entworfen oder diese Werte nicht gespeichert haben.

8
Aaron Bertrand

Dies gibt den gesuchten Wert zurück. Ich würde dringend empfehlen, wenn Sie die Kontrolle über diesen Prozess haben, die Speicherung von Daten in diesem Format einzustellen.

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)

(enter image description here

Um dies in eine Funktion zu verpacken, die eine Tabelle zurückgibt (eine sogenannte Table-Valued-Funktion), können Sie Folgendes tun:

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

Um dies auszuführen, können Sie entweder:

SELECT *
FROM dbo.GetProductCodeFromVARBINARY(0x008B010000000089FF32323633393933352D4B434E000000);

was dies zurückgibt:

(enter image description here

Wenn Sie dies für eine andere Tabelle mit den VARBINARY-Werten JOIN benötigen, können Sie Folgendes tun:

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

Ergebnisse:

(enter image description here

2
Max Vernon