如何xPath到SQL Server中的select语句中的值?

时间:2015-03-03 18:54:21

标签: sql sql-server xpath xquery

XML位于表格的列中。我想选择这个特定值:

<CreditDebitAdjustments xmlns="http://....">
  <CreditDebitAdjustment>
    <Header>
      <CreditDebitAdjustmentHeader>
        <Amount>-111.58</Amount>

这是我试图做的事情:

SELECT 
   *, 
   XMLPayload.query('/CreditDebitAdjustments/CreditDebitAdjustment/Header/CreditDebitAdjustmentHeader/Amount') AS Amount 
FROM Table
WHERE CustomerID = 8

如何提取值-111.58?

2 个答案:

答案 0 :(得分:2)

您需要使用value()方法并定义XML Namespaces

WITH XMLNAMESPACES(DEFAULT 'http://.......')
SELECT XMLPayload.value('/CreditDebitAdjustments[1]/CreditDebitAdjustment[1]/Header[1]/CreditDebitAdjustmentHeader[1]/Amount[1]', 'decimal(10, 4)') AS Amount
FROM Table
WHERE CustomerID = 8;

由于value()方法需要单例,因此您只能从每个节点获取第n个匹配项(在上面的示例中,每个节点都是第1个)。如果您需要完成所有事件,则需要将其与nodes()结合使用:

WITH XMLNAMESPACES(DEFAULT 'http://.......')
SELECT X.value('Amount[1]', 'decimal(10, 4)') AS Amount
FROM Table AS t
CROSS APPLY XMLPayload.nodes('/CreditDebitAdjustments/CreditDebitAdjustment/Header/CreditDebitAdjustmentHeader') AS n (X)
WHERE CustomerID = 8;

简单示例:

DECLARE @T TABLE (XMLPayload XML)
INSERT @T
VALUES ('<CreditDebitAdjustments>
  <CreditDebitAdjustment>
    <Header>
      <CreditDebitAdjustmentHeader>
        <Amount>-111.58</Amount>
      </CreditDebitAdjustmentHeader>
      <CreditDebitAdjustmentHeader>
        <Amount>5</Amount>
      </CreditDebitAdjustmentHeader>
    </Header>
  </CreditDebitAdjustment>
    </CreditDebitAdjustments>');

SELECT XMLPayload.value('/CreditDebitAdjustments[1]/CreditDebitAdjustment[1]/Header[1]/CreditDebitAdjustmentHeader[1]/Amount[1]', 'decimal(10, 4)') AS Amount
FROM @T;

SELECT X.value('Amount[1]', 'decimal(10, 4)') AS Amount
FROM @T AS t
CROSS APPLY XMLPayload.nodes('/CreditDebitAdjustments/CreditDebitAdjustment/Header/CreditDebitAdjustmentHeader') AS n (X);

答案 1 :(得分:1)

您需要尊重在XML上定义的XML命名空间!

<CreditDebitAdjustments xmlns="http://....">
                         ********************

在您的查询中包含此内容,您应该没问题:

WITH XMLNAMESPACES(DEFAULT 'http://.......')
  SELECT 
      XMLPayload.value('(/CreditDebitAdjustments/CreditDebitAdjustment/Header/CreditDebitAdjustmentHeader/Amount)[1]', 'decimal(20,2)') AS Amount 
  FROM Table
  WHERE CustomerID = 8