将二进制文件选择为 XML 将被转换为base64
编码字符串。
DECLARE @SomeString NVARCHAR(10)='abcdefg';
DECLARE @SomeBinary VARBINARY(MAX)=CAST(@SomeString AS VARBINARY(MAX));
DECLARE @Xml XML=(SELECT @SomeBinary FOR XML PATH('row'),ROOT('root'),TYPE);
SELECT @xml;
-- 二进制被隐式转换为base64
<root>
<row>YQBiAGMAZABlAGYAZwA=</row>
</root>
--读这个,会隐式地重新编码这个:
SELECT CAST(@xml.value(N'(/root/row/text())[1]',N'varbinary(max)') AS NVARCHAR(MAX));
更新
您的使用限制FROM OPENXML
是您真正应该讨论的问题!如果您被限制在下一次长途旅行中使用马匹,您也会讨论这个问题:-D
您上面的代码返回一个base64
编码值
SELECT @ks
返回
<data>SABlAGwAbABvAFcAbwByAGwAZAAhAA==</data>
阅读有关FROM OPENXML
二进制数据的文档(K 节)。建议是:使用 XML 的.value()
方法将其转换回来!
EXEC sp_xml_preparedocument @hDoc OUTPUT, @ks
DECLARE @base64String AS NVARCHAR(MAX);
select @base64String = data
FROM OPENXML(@hdoc, '/',2)
WITH
(
data varbinary(max) 'data'
)
SELECT 'Target_data', @base64String, CAST(CAST(N'<x>' + @base64String + N'</x>' AS XML).value(N'.',N'varbinary(max)') AS NVARCHAR(MAX));
EXEC sp_xml_removedocument @hDoc;
这可行,但这是一种相当愚蠢的方法。为什么不使用该方法直接从 XML 中读取值.value()
?这就像最后一英里的马和飞机的长途旅行......
FROM OPENXML
有很多限制,很慢,需要在需要时解析完整的 XML,不可内联,不能在 aVIEW
或 an中使用iTVF
,笨拙,难以阅读并且 - 嗯 - 过时了。
更新 2
在评论中我已经告诉过你,你的限制指向一些绝对过时的设置。你宁愿改变那些...
如果您必须坚持使用它,您可以将二进制值作为 hexString 插入到您的 XML 中,并使用动态创建的语句来取回该值:
DECLARE @hexString VARCHAR(1000)=master.sys.fn_varbintohexstr(CAST('Some text you want to convert!' AS VARBINARY(1000)));
SELECT @hexString;
DECLARE @cmd VARCHAR(MAX)='SELECT CAST(' + @hexString + ' AS VARCHAR(1000))';
EXEC(@cmd);
但这是一个非常丑陋的黑客......现在必须洗手:-D