我相信我对SQL Server 2000处理十六进制数字的方式有疑问。
如果我做了
select * from table where [timestamp] = 44731446
它返回的行显示时间戳为0x0000000202AA8C36
如果我
同样在另一张表中select * from table2 where [timestamp] = 44731446
它返回的行显示时间戳为0x0000000002AA8C36(注意缺少的2)
MS Calc告诉我第一个时间戳= 8634666038(十进制),第二个时间戳= 44731446(十进制),与两个表上的原始查询相匹配。
那么为什么SQL Server会返回不同的数字,但是却成功查询了它?我相信这是更新问题的路径,我所在的行不会更新。
答案 0 :(得分:2)
长话短说,二进制到整数转换是截断数据:
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
根据联机丛书(2008年,我没有2000):
转换为[非字符串数据类型]时 二进制或varbinary,数据是 在左边填充或截断。 填充是通过使用实现的 十六进制零