【问题标题】:Convert a BINARY stored as VARCHAR to BINARY将存储为 VARCHAR 的 BINARY 转换为 BINARY
【发布时间】:2015-02-17 16:19:25
【问题描述】:

我从表(源)中执行INSERT SELECT,其中每列都是VARCHAR 数据类型。

其中一列存储二进制数据,如

'0003f80075177fe6'

我在其中插入的目标表具有相同的列,但具有正确的数据类型 BINARY(16)

INSERT INTO destination
(
    column1,        --type of BINARY(16)
    ...
)
SELECT
    CONVERT(BINARY(16),[varchar_column_storing_binary_data]),   --'0003f80075177fe6'
FROM source
GO

当我插入它,然后选择目标表时,我得到了与BINARY16 列不同的值:

0x30303033663830303735313737666536

它看起来不像是同一个值。

将存储为VARCHAR 的二进制数据转换为BINARY 列的正确方法应该是什么?

【问题讨论】:

    标签: sql sql-server sql-server-2008 tsql


    【解决方案1】:

    您得到的结果是因为字符串“0003f80075177fe6”(VARCHAR 值)被转换为代码点,并且这些代码点作为二进制值提供。由于您可能正在使用与 ASCII 兼容的排序规则,这意味着您将获得 ASCII 码点:0 是 48(30 十六进制),f 是 102(66 十六进制)等等。这解释了30 30 30 33 66 38 30 30...

    您想要做的是将字符串解析为字节的十六进制表示 (00 03 f8 00 75 71 77 fe 66)。 CONVERT 接受一个额外的“样式”参数,允许您转换十六进制字符串:

    SELECT CONVERT(BINARY(16), '0003f80075177fe6', 2)
    

    样式 2 将十六进制字符串转换为二进制。 (样式 1 对以“0x”开头的字符串也是如此,这里不是这种情况。)

    请注意,如果少于 16 个字节(如本例所示),则该值右填充零 (0x0003F80075177FE60000000000000000)。如果您需要左填充,则必须自己做:

    SELECT CONVERT(BINARY(16), RIGHT(REPLICATE('00', 16) + '0003f80075177fe6', 32), 2)
    

    最后,请注意,无需转换即可指定二进制文字,只需在它们前面加上“0x”而不使用引号:SELECT 0x0003f80075177fe6 将返回BINARY(8) 类型的列。与此查询无关,只是为了完整性。

    【讨论】:

    • 嘿,Jeroen,这行得通……这对我来说不是很直观,但最终还是有意义的……如果你在这里,我会拥抱你,谢谢!
    • 我已经扩展了答案,试图消除任何剩余的困惑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-19
    • 1970-01-01
    • 2014-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多