2015-06-15 51 views
4

我有樣本值的XML列如何讓使用XPath和XQuery在SQL Server

<error> 
    <errorno>BL04002055</errorno> 
    <description>Smart Rule PROJECT_COUNTRYCODE_VAL Violated</description> 
    <description2>Country Code is required</description2> 
    <correction /> 
</error> 
<error> 
    <errorno>BL01001973</errorno> 
    <description /> 
    <description2>Error While Saving the Project info</description2> 
    <correction /> 
</error> 
<error> 
    <errorno>Unable to Create Custom Object</errorno> 
    <description /> 
    <description2>Smart Rule PROJECT_COUNTRYCODE_VAL Violated: Country Code is required 
Error While Saving the Project info</description2> 
    <correction /> 
</error> 

我想選擇逗號分隔

select * 
--, Response.value(''/error/description2/text()'', 'varchar(8000)') as parsedString 
, Response.query('/error/description2/text()') as parsedString 
from #temp 

兩個問題的內容描述值逗號分隔的XML值這裏。

  1. 我無法在上面的查詢中運行值函數。
  2. 使用查詢,我得到值連接,沒有空格或逗號。所以我需要在連接值上添加一些空格或逗號。

回答

6

SQL Server不實現XPath函數string-join,所以你需要採取兩個步驟,首先將所有的條款中提取使用nodes()行;

SELECT n.value('.', 'VARCHAR(100)') AS parsedString 
FROM #temp AS t 
     CROSS APPLY t.Response.nodes('/error/description2') r (n); 

,讓你自己的價值觀爲行:

parsedString 
---------------------------------------------------------------------------- 
Country Code is required 
Error While Saving the Project info 
Smart Rule PROJECT_COUNTRYCODE_VAL Violated: Country Code is required 
Error While Saving the Project 

然後你就可以添加你的分隔符和將它們連接起來備份,使用FOR XML PATH(''), TYPE,最後使用STUFF刪除第一個分隔符:

SELECT STUFF((SELECT ',' + n.value('.', 'VARCHAR(100)') AS parsedString 
       FROM #temp AS t 
         CROSS APPLY t.Response.nodes('/error/description2') r (n) 
       FOR XML PATH(''), TYPE 
      ).value('.', 'VARCHAR(MAX)'), 1, 1, '') AS ParsedString; 

FULL WORKING EX AMPLE

DECLARE @X XML = '<error> 
    <errorno>BL04002055</errorno> 
    <description>Smart Rule PROJECT_COUNTRYCODE_VAL Violated</description> 
    <description2>Country Code is required</description2> 
    <correction /> 
</error> 
<error> 
    <errorno>BL01001973</errorno> 
    <description /> 
    <description2>Error While Saving the Project info</description2> 
    <correction /> 
</error> 
<error> 
    <errorno>Unable to Create Custom Object</errorno> 
    <description /> 
    <description2>Smart Rule PROJECT_COUNTRYCODE_VAL Violated: Country Code is required 
Error While Saving the Project info</description2> 
    <correction /> 
</error>'; 

SELECT STUFF((SELECT ',' + n.value('.', 'VARCHAR(100)') AS parsedString 
       FROM (SELECT @X) AS t (Response) 
         CROSS APPLY t.Response.nodes('/error/description2') r (n) 
       FOR XML PATH(''), TYPE 
      ).value('.', 'VARCHAR(MAX)'), 1, 1, '') AS ParsedString; 
2

或者,您可以使用XQuery forif..else語句的組合來構建逗號分隔值:

DECLARE @xml XML = 'your xml string here' 

SELECT CONVERT(VARCHAR(MAX), 
      @xml.query(' 
        for $e in error 
        return 
         if($e is /error[last()]) 
          then string($e/description2[1]) 
         else concat($e/description2[1], ", ") 
        ') 
     ) As ParsedString 

SQLFiddle Demo

簡要說明:

僅噹噹前error元素是最後一個error元素時,XQuery只是遍歷error元素並返回子元素description2。否則,返回值爲description2的值與逗號連接。