如何将 xPath 指向 SQL 服务器中 select 语句中的值?

how do I xPath to a value in a select statement in SQL Server?

XML 在 table 的列中。我要select这个具体值:

<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?

您需要使用 value() method and define your 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);

您需要尊重 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