将存储为VARCHAR的BINARY转换为BINARY

时间:2015-02-17 16:19:25

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

我从表(源)中执行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列的正确方法是什么?

1 个答案:

答案 0 :(得分:8)

你得到的结果是因为字符串" 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)类型的列。与此查询无关,但仅为完整性。