将二进制数据导出到xml并在sql server中读回相同内容

时间:2018-02-09 13:26:34

标签: xml tsql sql-server-2012 base64 varbinarymax

我们要求将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

1 个答案:

答案 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,笨拙,难以阅读 - 嗯 - 过时。

更新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