Проблемы преобразования Sql-сервера из двоичных данных в числовые данные - PullRequest
0 голосов
/ 28 июня 2018

Я пытаюсь сохранить значения из одной таблицы CDC сервера Sql, которая имеет тип данных столбца как «Binary (10)». Я хочу преобразовать его в «числовой» формат, а затем преобразовать обратно в «двоичный (10)».

Например,

declare @binary_data binary(10),@binary2 as binary(10)

select  @binary_data = 0x000000180003727C0006

Select Convert(int,0x00000018) as [PrecesionValue]
Select Convert(int,0x000) as [ScaleValue]

declare @Numeric as numeric(24,0) --Setting Numeric(PrecesionValue, ScaleValue)

Select @Numeric =Convert(numeric(24,0),@binary_data) 

Select @binary2 = Convert(binary(10),@Numeric) 

print @binary_data
print @Numeric
print @binary2

Выход:

0x000000180003727C0006  //Initial binary data

393340                  //Converted Numeric value

0x0000180000017C000600  //Re-converted back to Binary value

Если вы видите, повторно преобразованное двоичное значение не соответствует исходному значению. Можете ли вы проверить, где я иду не так?

1 Ответ

0 голосов
/ 01 июля 2018

Чтобы "перевести" 10-байтовый двоичный файл во что-то недвоичный , вам понадобится тип данных, который имеет как минимум 10 байтов. Но вам не следует полагаться на битовый шаблон, используемый SQL Server для хранения сложного типа данных.

Я хочу предложить два подхода:

--this is your binary
declare @binary1 binary(10) 
set @binary1 = 0x000000180003727C0006;
select  @binary1; 

--XML will translate binaries to base64 implicitly
declare @string varchar(100);
set @string = (SELECT @binary1 AS [*] FOR XML PATH(''),TYPE).value('.','varchar(100)');
select @string,LEN(@string);

--this is the approach to translate the base64 back to a binary
declare @binary2 binary(10);
set @binary2=CAST('<x>' + @string + '</x>' AS XML).value('.','varbinary(10)');
select @binary2; 

--the second approach is a GUID (16 byte)
declare @guid uniqueidentifier;
set @guid=@binary1
select @guid;

--a GUID is a simple chain of bytes, easy to cast
set @binary2=CAST(@guid AS VARBINARY(10));
select @binary2; 

ОБНОВЛЕНИЕ: мне пришла в голову еще одна идея

Существует причина, по которой двоичные и строковые типы объединяются в одной теме . Вы можете разбить ваш 10-байтовый двоичный файл на куски и считать их разделенными числами:

declare @binary1 binary(10) 
set @binary1 = 0x00000180003727C0006;
select  @binary1,SUBSTRING(@binary1,1,4) AS Byte0to3 
                ,SUBSTRING(@binary1,5,4) AS Byte4to8
                ,SUBSTRING(@binary1,10,2) AS Byte9to10;

declare @int1 INT, @int2 INT, @smallint smallint;
select  @int1 =     SUBSTRING(@binary1,1,4)  
       ,@int2 =     SUBSTRING(@binary1,5,4) 
       ,@smallint = SUBSTRING(@binary1,10,2);
select @int1,@int2,@smallint;

declare @binary2 binary(10);
set @binary2 = CAST(@int1 AS binary(4)) + CAST(@int2 AS binary(4)) + CAST(@smallint AS binary(2));
select @binary2;
...