SQL从XML字段

时间:2017-06-13 19:50:52

标签: sql sql-server xml tsql

我希望格式化XML列中的数据。我搜索了stackoverflow并找到了一些很好的例子。

来源:CONVERTING SQL NVARCHAR(MAX) TO XML and getting a Value from XML string

我的查询如下:

SELECT
    b.x.value('/CustomDataResponse[1]/FieldData[1]/FieldData[1]/FieldName[1]', 'varchar(100)') as Name
    ,b.x.value('/CustomDataResponse[1]/FieldData[1]/FieldData[1]/FieldDataValue[1]', 'varchar(100)') as Value

FROM
    MyTable a 
    CROSS APPLY (
                  SELECT
                   CAST(CAST ([XMLVAL] AS NVARCHAR(MAX)) AS XML) x
                ) b;

XMl如下所示:

<CustomDataResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <AccountID>0</AccountID>
  <UserNumber xsi:nil="true" />
  <Workstation xsi:nil="true" />
  <SerialNumber xsi:nil="true" />
  <Set>0</Set>
  <SecurityID>0000000</SecurityID>
  <SecurityType>Equity</SecurityType>
  <FieldData>
    <FieldData>
      <FieldName>ISSUER</FieldName>
      <FieldDataValue>ABC INC</FieldDataValue>
    </FieldData>
    <FieldData>
      <FieldName>TICKER</FieldName>
      <FieldDataValue>ABC</FieldDataValue>
    </FieldData>
    <FieldData>
      <FieldName>SECURITY_TYP</FieldName>
      <FieldDataValue>PUBLIC</FieldDataValue>
    </FieldData>
  </FieldData>
</CustomDataResponse>

使用此查询和xml,我得到结果为

enter image description here

如何扩展它以使用其他字段,如Ticker,Security_typ? 谢谢你的帮助。

2 个答案:

答案 0 :(得分:2)

一种方法是

SELECT Issuer = c.x.value('FieldData[FieldName[. = ''ISSUER'']][1]/FieldDataValue[1]'
                         ,'varchar(100)'),
       Ticker = c.x.value('FieldData[FieldName[. = ''TICKER'']][1]/FieldDataValue[1]'
                         ,'varchar(100)'),
       SecurityType = c.x.value('FieldData[FieldName[. = ''SECURITY_TYP'']][1]/FieldDataValue[1]'
                         ,'varchar(100)')
FROM   MyTable a
       CROSS APPLY (SELECT CAST(CAST ([XMLVAL] AS NVARCHAR(MAX)) AS XML) x) b
       CROSS APPLY b.x.nodes('/CustomDataResponse[1]/FieldData[1]') c(x);  

顺便说一下XMLVALNVARCHAR(MAX)的中间演员?

答案 1 :(得分:2)

又一个选择

Declare @YourTable table (ID int,XMLVal varchar(max))
Insert Into @YourTable values
(1,'<CustomDataResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><AccountID>0</AccountID><UserNumber xsi:nil="true" /><Workstation xsi:nil="true" /><SerialNumber xsi:nil="true" /><Set>0</Set><SecurityID>0000000</SecurityID><SecurityType>Equity</SecurityType><FieldData><FieldData><FieldName>ISSUER</FieldName><FieldDataValue>ABC INC</FieldDataValue></FieldData><FieldData><FieldName>TICKER</FieldName><FieldDataValue>ABC</FieldDataValue></FieldData><FieldData><FieldName>SECURITY_TYP</FieldName><FieldDataValue>PUBLIC</FieldDataValue></FieldData></FieldData></CustomDataResponse>')

Select A.ID
      ,C.*
 From  @YourTable A
 Cross Apply (Select XMLData=cast(A.XMLVal as xml)) B
 Cross Apply (
                Select [Name]  = r.n.value('(FieldName)[1]','varchar(50)')
                      ,[Value] = r.n.value('(FieldDataValue)[1]','varchar(50)')
                 From  B.[XMLData].nodes('CustomDataResponse/FieldData/*') r(n)
             ) C

返回

ID  Name            Value
1   ISSUER          ABC INC
1   TICKER          ABC
1   SECURITY_TYP    PUBLIC