我们要求将xml中的varbinary数据作为标记发送,我们必须在另一个sql server db中读取xml,我们必须接收源数据,但我无法做到。
这是一段代码:
DECLARE @cmds NVARCHAR(MAX)
DECLARE @obfoo VARBINARY(MAX)
DECLARE @ks XML,@hDoc INT
--convert some text to binary?
SET @cmds = N'HelloWorld!'
SET @obfoo = CAST(@cmds AS VARBINARY(MAX))
SELECT 'Source data',@cmds,@obfoo as source_data
SELECT @ks =
(SELECT @obfoo
FOR XML PATH('data'))
SELECT @ks
EXEC sp_xml_preparedocument @hDoc OUTPUT, @ks
select @obfoo =
CONVERT(varbinary(max),data)
FROM OPENXML(@hdoc, '/',2)
WITH
(
data nvarchar(max) 'data'
)
SELECT 'Target_data', CAST(@obfoo AS NVARCHAR(MAX) ),@obfoo
答案 0 :(得分:0)
将二进制文件选择为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;
- Binary隐式转换为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>
阅读this documentation about FROM OPENXML
and binary data (section K)。建议是:使用XML&#39; .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;
这很有效,但却是一种相当愚蠢的方法。为什么不使用.value()
方法直接从XML中读取值?这就像是最后一英里的马和飞机的远距离旅行......
FROM OPENXML
有很多限制,很慢,需要在需要时解析完整的XML,不是内联,不能在VIEW
中使用iTVF
,笨拙,难以阅读 - 嗯 - 过时。
在评论中,我已经告诉过您,您的限制指向了一些绝对过时的设置。你应该改变那些......
如果必须坚持下去,可以将二进制值作为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