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 字符串。
您的最终结果只是您输入字符串的二进制模式:
我们目前在 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 字符串。
您的最终结果只是您输入字符串的二进制模式: