2017-06-13 70 views
1

我正在尋找格式化來自XML列的數據。我搜索了stackoverflow並找到了一些很好的例子。SQL從XML字段獲取數據

來源: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? 感謝您的幫助。

+0

確定。我發佈了XML。 – ProgSky

回答

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); 

順便說爲什麼XMLVAL中間投給NVARCHAR(MAX)

+0

太棒了!作品!您是對的,無需將XMLVAL轉換爲NVARCHAR(MAX) – ProgSky

+1

最令人印象深刻。我假設OP想要的行,但即使如此,你的方法不會發生在我+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 
+0

謝謝約翰。你的解決方案也能工作 – ProgSky