SQL 字符串到 varbinary 到 XML 不同于 nvarchar

SQL string to varbinary through XML different than nvarchar

我们目前在 SQL 中有一个我根本不明白的函数。

目前我们将 nvarchar 转换为 XML,然后 select XML 值,并将其转换为 varbinary。

当我尝试对此进行简化以将 nvarchar 直接转换为 varbinary 时,输出不同...为什么?

--- Current situation:
Declare @inputString nvarchar(max) = '4d95605d1b8f3bca5ea3e0d2af26027004d17218152e726da0622d669a71f85c'

--1: input to XML
declare @inputXML XML = convert(varchar(max), @inputString)

--2: input XML to binary
declare @inputBinray varbinary(max) = @inputXML.value('(/)[1]', 'varbinary(max)')

select @inputString -- 4d95605d1b8f3bca5ea3e0d2af26027004d17218152e726da0622d669a71f85c
select @inputXML -- 4d95605d1b8f3bca5ea3e0d2af26027004d17218152e726da0622d669a71f85c
select @inputBinray -- 0xE1DF79EB4E5DD5BF1FDDB71AE5E6B77B477669FDBAD36EF4D38775EF6D7CD79D9EEF6E9D6B4EB6D9DEBAF5AEF57FCE5C
--- New situation
--1: Input to binary
declare @inputString2 varbinary(max) = CAST(@inputString as varbinary(max));

select @inputString2 -- 0x3400640039003500360030003500640031006200380066003300620063006100350065006100330065003000640032006100660032003600300032003700300030003400640031003700320031003800310035003200650037003200360064006100300036003200320064003600360039006100370031006600380035006300

使用 value() 函数获取指定为 varbinary(max) 的 XML 值将读取数据,就好像它是 Base64 编码的一样。将字符串转换为 varbinary(max) 不会,它将它视为任何字符串。

如果您使用输入字符串 QQA=,即 UTF-16 LE 编码为 Base64 的字母 A,您会更清楚地看到发生了什么。

XML 给你 0x4100,字母 A 的 varbinary,直接在字符串上转换给你 0x5100510041003D00 其中有两个 5100 = "Q" 当然还有一个 4100 = "A" 后跟一个 3D00 = "="

可能是我弄错了,但是 - 如果我理解正确的话 - 我想你只是想从 HEX 字符串中得到一个 真正的二进制文件 ,它只是 看起来 像一个二进制文件。正确吗?

上面我写了“简单”,但是这在前一段时间一点都不简单

我现在不确定,但我认为是版本 v2012,它增强了 CONVERT()(阅读二进制值和第三个参数的工作原理)并试试这个:

DECLARE @hexString VARCHAR(max)='4d95605d1b8f3bca5ea3e0d2af26027004d17218152e726da0622d669a71f85c';

SELECT CONVERT(varbinary(max),@hexString,2);

结果是真实二进制

0x4D95605D1B8F3BCA5EA3E0D2AF26027004D17218152E726DA0622D669A71F85C

您的问题可能是什么原因:

很久以前,我认为直到 v2005,XML 中 varbinaries 的默认编码是 HEX 字符串。后来改成了base64。可能是,您的代码在非常旧的环境中使用并升级到更高版本?

今天我们使用 XML 来创建和读取 base64,否则不支持。也许您的代码对 HEX 字符串做了类似的事情...?

对此还有一个提示:New Situation 示例中的许多 00 清楚地表明,这是一个两字节编码的 NVARCHAR 字符串.相反,您的 Current Situation 显示了一个简单的 HEX 字符串。

您的最终结果只是您输入字符串的二进制模式: