SQL Server 十六进制处理

发布于 2024-09-30 19:07:51 字数 471 浏览 2 评论 0原文

我相信 SQL Server 2000 处理十六进制数字的方式有问题。

如果我执行一个

select * from table where [timestamp] = 44731446

操作,它返回的行将时间戳显示为 0x0000000202AA8C36

同样在另一个表中,如果我

select * from table2 where [timestamp] = 44731446

返回的行将时间戳显示为 0x0000000002AA8C36 (注意缺少 2)

MS Calc 告诉我第一个时间戳 = 8634666038(十进制),第二个时间戳 = 44731446(十进制),与我对两个表的原始查询相匹配。

那么为什么 SQL Server 返回不同的数字,但查询成功呢?我相信这是我遇到的更新问题的途径,其中行不会更新。

I believe I'm having a problem with the way SQL Server 2000 handles hexadecimal numbers.

If I do a

select * from table where [timestamp] = 44731446

the row that it returns shows the timestamp as 0x0000000202AA8C36

Equally in another table if I

select * from table2 where [timestamp] = 44731446

the row that it returns shows the timestamp as 0x0000000002AA8C36 (notice the missing 2)

MS Calc tells me that the first timestamp = 8634666038 in decimal and the second timestamp = 44731446 in decimal which matches my original query on both tables.

So why is SQL Server returning a different number, yet successfully querying it? I believe this is the route of an update problem I'm having where the row won't update.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

晚雾 2024-10-07 19:07:51

长话短说,二进制到整数的转换会截断数据:

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 年):

当[非字符串数据类型]转换为
binary 或 varbinary,数据是
左侧填充或截断。
填充是通过使用实现的
十六进制零

Long story short, the binary to integer conversion is truncating data:

select cast(0x0000000202AA8C36 as int)

A TIMESTAMP column is really BINARY(8), so your query is comparing a BINARY(8) value to an INT value; because INT has the higher precedence, MSSQL converts the BINARY(8) value to INT before comparing them.

But, 0x0000000202AA8C36 (or 8634666038) is too big to be represented as INT, so MSSQL has to truncate it first, and it truncates to the same value as 0x0000000002AA8C36. This might be a little clearer:

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

According to Books Online (for 2008, I don't have 2000):

When [non-string data types] are converted to
binary or varbinary, the data is
padded or truncated on the left.
Padding is achieved by using
hexadecimal zeros

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文