1

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

1 回答 1

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;

-- 二进制被隐式转换为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

于 2018-02-09T20:07:55.077 回答