16進数として保存された値を持つ列があります。
このクエリを実行すると:
select column from table
where column like '%22639935-KCN%';
これは私が得る出力です:
0x24000000008B010000000089FF32323633393933352D4B434E000000
出力をvarcharに変換したいと思います。これにより、likeステートメントの内容に似た値が得られます。
これまでの私の試みは:
SELECT CONVERT(VARCHAR(MAX),
0x24000000008B010000000089FF32323633393933352D4B434E000000)
SELECT CONVERT(VARCHAR(MAX), CONVERT(VARBINARY(MAX),
'0x24000000008B010000000089FF32323633393933352D4B434E000000', 2))
しかし、私はこの結果を得ます:
$
この16進値をvarcharに変換するにはどうすればよいですか?
Varbinary文字列になんらかのナンセンスが注入されているようです。 2つの_00
_値のシーケンスはすべてnull文字であるため、変換時に文字列が終了します。最初の文字は_0x24
_(ドル記号)です。そのため、出力は単なるドル記号です。
_SELECT CONVERT(varchar(60), 0x2400....anything....);
-- is equivalent to:
SELECT CONVERT(varchar(60), 0x24);
_
さて、あなたの文字列を取り、_00
_シーケンスをすべて取り除いた場合:
_SELECT CONVERT(VARCHAR(60), 0x248B0189FF32323633393933352D4B434E);
_
私は何かに近づきます。繰り返しますが、そこには大量のゴミがありますが、あなたが求めている文字列isがあります:
_$‹‰ÿ22639935-KCN
_
元のガベージを無視して元の値を取得し、それに対してRIGHT()
を実行することで無視できますが、これは文字列の重要な部分が常に同じ長さであることを前提としています(それが真であるかどうかはわかりません)。 。
_SELECT CONVERT(VARCHAR(60),
RIGHT(0x24000000008B010000000089FF32323633393933352D4B434E000000, 15));
_
またはSUBSTRING
を使用しますが、これは文字列の先頭のガベージが常に同じ長さであることを前提としています:
_SELECT CONVERT(VARCHAR(60),
SUBSTRING(0x24000000008B010000000089FF32323633393933352D4B434E000000, 14, 46));
_
whyごみがそこにあることと、それが何か追加の意味があるかどうかを伝えることもできません。最初に、値がこのようにエンコードされた方法を見つける必要があります。エンコードしたい値_22639935-KCN
_は、varbinary
とは少し違って見えるはずです。
_SELECT CONVERT(VARBINARY(32), '22639935-KCN');
--------------------------
0x32323633393933352D4B434E
_
したがって、ここでも、この値がこのようにエンコードされなかった理由を見つけるために、いくつかの調査を行う必要があります。私たちはあなたのシステムを設計したりそれらの値を保存したりしていないので、これらすべてに答えることはできません。
これにより、探しているvalueが返されます。このプロセスを制御している場合は、この形式でのデータの保存を停止することを強くお勧めします。
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)
これをテーブルを返す関数(いわゆるテーブル値関数)にラップするには、次のようにします。
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
これを実行するには、次のいずれかを実行できます。
SELECT *
FROM dbo.GetProductCodeFromVARBINARY(0x008B010000000089FF32323633393933352D4B434E000000);
これはこれを返します:
または、これをVARBINARY値を含む別のテーブルにJOIN
する必要がある場合は、次のようにすることができます。
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
結果: