我从表(源)中执行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
列的正确方法是什么?
答案 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)
类型的列。与此查询无关,但仅为完整性。