SQL Server шестнадцатеричная обработка - PullRequest
0 голосов
/ 08 ноября 2010

Мне кажется, у меня проблема с тем, как SQL Server 2000 обрабатывает шестнадцатеричные числа.

Если я сделаю

select * from table where [timestamp] = 44731446

, строка, которую он возвращает, показывает метку времени как 0x0000000202AA8C36

Точно так же в другой таблице, если I

select * from table2 where [timestamp] = 44731446

строка, которую он возвращает, показывает метку времени как 0x0000000002AA8C36 (обратите внимание на пропущенные 2)

MS Calc говорит мне, что первыйотметка времени = 8634666038 в десятичном формате и вторая отметка времени = 44731446 в десятичном формате, что соответствует моему исходному запросу в обеих таблицах.

Так почему SQL Server возвращает другое число, но при этом успешно запрашивает его?Я полагаю, что это путь к проблеме с обновлением, в которой строка не будет обновляться.

1 Ответ

2 голосов
/ 08 ноября 2010

Короче говоря, двоичное преобразование в целое число усекает данные:

select cast(0x0000000202AA8C36 as int)

Столбец TIMESTAMP действительно BINARY (8), поэтому ваш запрос сравнивает значение BINARY (8) со значением INT; поскольку INT имеет более высокий приоритет, MSSQL преобразует значение BINARY (8) в INT перед их сравнением.

Но 0x0000000202AA8C36 (или 8634666038) слишком велик, чтобы быть представленным как INT, поэтому MSSQL должен сначала его обрезать, и он усекается до того же значения, что и 0x0000000002AA8C36. Это может быть немного яснее:

create table dbo.t (tstamp binary(8) not null)
go

insert into dbo.t values (0x0000000202AA8C36)
insert into dbo.t values (0x0000000002AA8C36)
go

-- returns 2 rows
select * from dbo.t where tstamp = 44731446
-- returns 1 row
select * from dbo.t where tstamp = cast(44731446 as bigint)
go

drop table dbo.t 
go

По данным Books Online (за 2008 год у меня нет 2000):

Когда [нестроковые типы данных] конвертируются в двоичные или переменные, данные дополненный или усеченный слева. Заполнение достигается с помощью шестнадцатеричные нули

...