如何在sql server中读取xml中的varbinary数据

时间:2016-04-08 14:14:05

标签: sql-server xml sql-server-2008 varbinary

我的数据是XML,如

<Values>
  <Id>7f8a5d20-d171-42f5-a222-a01b5186a048</Id>
  <DealAttachment>
    <AttachmentId>deefff3f-f63e-4b4c-8e76-68b6db476628</AttachmentId>
    <IsNew>true</IsNew>
    <IsDeleted>false</IsDeleted>
    <DealId>7f8a5d20-d171-42f5-a222-a01b5186a048</DealId>
    <AttachmentName>changes2</AttachmentName>
    <AttachmentFile>991049711010310132116104101321011099710510832115117981061019911645100111110101131011711210097116101329811110012132116101120116321151171031031011151161011003298121326610510810845100111110101131010011132110111116321151011101003210110997105108321051103299971151013211110232117112100971161011003299108105101110116115329811711632115101110100321051103299971151013211110232100101108101116101100329910810510111011611545321001111101011310991141019711610132973211510111297114971161013211697981081013211611132991111101169710511032117115101114115321161113211910411110932101109971051083211910510810832981013211510111011645100111110101131011611411711099971161013211610410132108111103321169798108101329710211610111432111110101321091111101161044510011111010113108411497110115108971161051111101154532100111110101131097100100321129711497109101116101114321161113210611198321161113211411711032115105108101110116108121451001011089712110110013101310131013101310131010511010211111410932981051081083210511032999711510132981111161043211711210097116105111110471001011081011161051111104432117112100971161051111103211910510810832110111116329810132105110102111114109101100</AttachmentFile>
    <AttachmentType>.txt</AttachmentType>
  </DealAttachment>
</Values>

其中AttachmentFile是varbinary(max)

DECLARE @AttachmentId uniqueidentifier, 
    @DealId uniqueidentifier, 
    @IsNew bit,
    @IsDeleted bit,
    @AttachmentName varchar(100), 

    @AttachmentFile varbinary(max), 
    @AttachmentType varchar(50) 

SET @DealId = @SubmitXml.value('(Values/Id/node())[1]', 'uniqueidentifier')
    SET @AttachmentId = @SubmitXml.value('(Values/DealAttachment/AttachmentId/node())[1]', 'uniqueidentifier')
    SET @IsNew = @SubmitXml.value('(Values/DealAttachment/IsNew/node())[1]', 'bit')
    SET @IsDeleted = @SubmitXml.value('(Values/DealAttachment/IsDeleted/node())[1]', 'bit')
    SET @AttachmentName = @SubmitXml.value('(Values/DealAttachment/AttachmentName/node())[1]', 'varchar(100)')
    SET @AttachmentFile = @SubmitXml.value('(Values/DealAttachment/AttachmentFile/node())[1]', 'varbinary(max)')
    SET @AttachmentType = @SubmitXml.value('(Values/DealAttachment/AttachmentType/node())[1]', 'varchar(50)')

但是,在上面的语句之后@AttachmentFile是NULL或空格。

1 个答案:

答案 0 :(得分:1)

@Ed是正确的,因为你以某种方式存储了每个字符的十进制ASCII值,而不是每个字符的十六进制值。你可以通过解码每一个来看到:

SELECT CHAR(99) + CHAR(104) + CHAR(97) + CHAR(110) + CHAR(103) + CHAR(101) +
       CHAR(32) + CHAR(116) + CHAR(104) + CHAR(101);
-- change the

但是你也可以看到,没有办法以编程方式解码,因为它是2位数和3位数值的混合。

如果您确实在该XML元素中存储了十六进制字节,则可以将其转换为具有相同二进制字节的VARBINARY(MAX),方法是首先从XML中将其作为普通VARCHAR(MAX)提取,然后将其转换为VARBINARY(MAX)使用CONVERT内置函数,指定2的“样式”。

SELECT CONVERT(VARBINARY(MAX), 'this is a test, yo!');
-- 0x74686973206973206120746573742C20796F21

DECLARE @SomeXML XML = N'
<Values>
  <DealAttachment>
    <AttachmentFile>74686973206973206120746573742C20796F21</AttachmentFile>
  </DealAttachment>
</Values>';

SELECT CONVERT(VARBINARY(MAX),
               @SomeXML.value('(/Values/DealAttachment/AttachmentFile/text())[1]',
                              'VARCHAR(MAX)'),
               2)
-- 0x74686973206973206120746573742C20796F21 (but as VARBINARY)

但是,尽管如此,理想情况下,您只需使用Convert.ToBase64String(也就是@Ed所提到的)Base64对二进制文件进行编码(因为您已经有byte[])。