【问题标题】:how do I xPath to a value in a select statement in SQL Server?如何 xPath 到 SQL Server 中的 select 语句中的值?
【发布时间】:2015-03-03 18:54:20
【问题描述】:

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?

【问题讨论】:

    标签: sql sql-server xpath xquery


    【解决方案1】:

    您需要使用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 次出现(上例中每个节点中的第一次出现)。如果您需要获取所有事件,则需要将其与 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);
    

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 2015-10-30
        • 1970-01-01
        • 2016-10-30
        • 2018-06-01
        • 2017-03-11
        • 2012-05-18
        • 1970-01-01
        • 2013-02-17
        • 2011-04-22
        相关资源
        最近更新 更多