【问题标题】:SQL Server: Hex values padded with zeros and bytes out of orderSQL Server:用零和字节乱序填充的十六进制值
【发布时间】:2018-07-27 22:31:05
【问题描述】:

我正在开发一个具有VARBINARY(255) 列的数据库,这对我来说没有意义。根据值的长度,该值可以是数字或单词。

对于存储的任何数字,它都是一个 4 字节的十六进制字符串 0x00000000,但从左到右读取,而字节从右到左读取。所以对于像255 这样的数字,它是0xFF000000,对于像745 这样的数字,它是0xE9020000。这是我不明白的部分,为什么它以这种方式存储而不是0x02E90x2E90x000002E9

说到单词,每个字符都存储为一个 4 字节的十六进制字符串,就像上面一样。像空格这样的东西存储为0x20000000,但像Sensor 这样的单词是0x53000000650000006E000000730000006F00000072000000 而不仅仅是0x53656E736F72

谁能向我解释为什么以这种方式存储数据?是否所有内容都表示为 4 字节字符串,因为存储的数字可以是完整的 4 字节,而文本用零填充以保持一致性?为什么将零填充到值的右侧?为什么第 4 个字节在前,第 1 个字节在后存储?

如果从 SQL 的角度来看这些都没有意义,我想可能是从我无权访问源的客户端应用程序以这种方式提供数据的。会这样吗?

最后,我想创建一个包含此列的报告,但已转换为正确的数字或​​单词。有没有比使用子字符串、修剪和递归更简单、性能更高的方法?

【问题讨论】:

  • 这不是 sql server 问题。存储的值是应用程序提供的值,它们的解释嵌入在应用程序逻辑中。您可能需要一些时间来阅读有关字节序(小与大)和字符串(ascii 与 unicode)的信息。由于数据类型是二进制的,可能所有值都是用于在应用程序中访问此信息的结构的直接内存映像 - 这可能是您看到额外字节的原因。但唯一知道的方法是查看应用逻辑。
  • @SMor 关于小端与大端的好点,这是一个很大的帮助!从那以后,我处理了从 LSB 到 MSB 的值,去掉了填充的零(在存储单词而不是数字的情况下),现在将单词作为我的最终结果!谢谢指点!

标签: sql-server hex


【解决方案1】:

在上述 cmets 中 Smor 的帮助下,我现在可以回答自己的问题了。

客户端应用程序提供了 4 字节的字符串,而数据库只接受它们,因为它们适合列的 VARBINARY(255) 数据类型和长度。由于应用程序以 little-endian 格式提供值,因此它们以这种方式存储在数据库中,最低有效字节在前,最高有效字节在后。由于大多数值都小于静态 4 字节长度,因此这些值在右侧填充零以符合 4 字节要求。

现在关于我对报告的问题,这是我想出的:

CASE 
    WHEN LEN(ByteValue) <= 4 
        THEN CAST(CAST(CAST(REVERSE(ByteValue) AS VARBINARY(4)) AS INT) AS VARCHAR(12))
    ELSE CAST(CONVERT(VARBINARY(255),REPLACE(CONVERT(VARCHAR(255),ByteValue,1),'000000',''),1) AS VARCHAR(100))
END AS PlainValue

在我的特定情况下,只有数字存储为 4 字节或更少的值,而单词存储为更长的值。这使我可以将较小的值分解为数字,而将较长的值分解为单词。

使用CASE WHEN,我可以指定只有4字节或更少的数据需要REVERSE()函数,因为这是将小端格式转换为SQL在转换时寻找的大端格式的最简单方法从十六进制到整数。由于REVERSE() 函数返回NVARCHAR 数据类型,我必须将其转换回VARBINARY,然后转换为INT,然后再转换为VARCHAR 以匹配第二种情况数据类型的数据类型。

任何长度超过 4 字节的字符串,专门用于单词,都属于 ELSE 部分,并允许我从十六进制值中去除多余的零,因此我只得到每个 4 字节长字符的第一个字节(在我的情况下唯一重要的部分)。通过将十六进制字符串转换为VARCHAR,我可以使用REPLACE() 函数轻松删除6 个重复的零。随着零的消失,将字符串转换回VARBINARY 可以轻松地转换为VARCHAR

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-20
    • 2017-09-13
    • 2019-03-01
    • 2015-01-14
    • 1970-01-01
    • 2014-02-20
    • 1970-01-01
    • 2019-07-27
    相关资源
    最近更新 更多