【问题标题】:In SQL, in XML datatype field, how do I query the data like a simple sql record?在 SQL 中,在 XML 数据类型字段中,如何像简单的 sql 记录一样查询数据?
【发布时间】:2020-11-29 13:32:17
【问题描述】:

我在表中有一个 XML 字段。

它将数据存储为

'<NewDataSet>
  <ClaimExpense>
    <ClaimNo>3003-LOB-0003</ClaimNo>
    <Office>3003</Office>
    <BranchId>1</BranchId>
    <CostCenterId>35</CostCenterId>
    <ServiceLineId>14</ServiceLineId>
    <ProjectId>62</ProjectId>
    <LCAmountCurr>AED</LCAmountCurr>
    <LCAmount>367.25</LCAmount>
    <FCCurr>USD</FCCurr>
    <FCAmount>100</FCAmount>
    <ExchangeRate>3.67252</ExchangeRate>
    <ExpenseDate>2020-11-03T00:00:00+04:00</ExpenseDate>
    <ClaimItemNo>ITM-004</ClaimItemNo>
    <GLAccount>10000000</GLAccount>
    <VatRate>5%</VatRate>
    <VatBaseAmount>349.76</VatBaseAmount>
    <VatAmount>17.49</VatAmount>
    <ClaimType>LOB</ClaimType>
    <ForPayment>357.25</ForPayment>
    <ForDeduction>0.00</ForDeduction>
    <EmpCode>2019-1194</EmpCode>
  </ClaimExpense>
  <ClaimExpense>
    <ClaimNo>3003-LOB-0003</ClaimNo>
    <Office>3003</Office>
    <BranchId>1</BranchId>

    <CostCenterId>35</CostCenterId>
    <ServiceLineId>14</ServiceLineId>
    <ProjectId>62</ProjectId>
    <LCAmountCurr>AED</LCAmountCurr>
    <LCAmount>90.00</LCAmount>
    <FCCurr>AED</FCCurr>
    <FCAmount>90</FCAmount>
    <ExchangeRate>1</ExchangeRate>
    <ExpenseDate>2020-11-03T00:00:00+04:00</ExpenseDate>
    <ClaimItemNo>ITM-005</ClaimItemNo>
    <GLAccount>10000000</GLAccount>
    <VatRate />

    <ClaimType>LOB</ClaimType>
    <ForPayment>357.25</ForPayment>
    <ForDeduction>0.00</ForDeduction>
    <EmpCode>2019-1194</EmpCode>

  </ClaimExpense>
</NewDataSet>'

现在我想像 sql 记录一样简单地查询它,我该怎么做?

我尝试了转换和一切,但没有运气。我只是希望它像任何可以选择,插入删除的sql记录一样简单。

累了,但没有运气:

   SELECT  
       Tbl.Col.value('GLAccount[0]', 'varchar')
     
FROM   @xml.nodes('/NewDataSet/ClaimExpense/GLAccount') Tbl(Col)  

【问题讨论】:

  • 需要使用Xquery获取数据。你试过什么了?为什么它不起作用? Stack Overflow 上有很多关于如何查询 XML 数据的示例;你不明白哪些答案?
  • @Larnu 已更新。检查
  • 另外,SQL 中没有“字段”或“记录”之类的东西。表有列和行。
  • 您的 XML 不包含任何称为“行”的节点。您需要使用实际节点的名称。
  • SELECT Tbl.Col.value('GLAccount[0]', 'varchar') FROM @xml.nodes('/NewDataSet/ClaimExpense/GLAccount') Tbl(Col)

标签: sql sql-server xml xquery


【解决方案1】:

查看如何为您的 XML 执行此操作。

SQL Fiddle

SQL

CREATE table tbl (ID INT IDENTITY PRIMARY KEY, xmldata XML);
insert into tbl (xmldata) values
(
  N'<NewDataSet>
    <ClaimExpense>
        <ClaimNo>3003-LOB-0003</ClaimNo>
        <Office>3003</Office>
        <BranchId>1</BranchId>
        <CostCenterId>35</CostCenterId>
        <ServiceLineId>14</ServiceLineId>
        <ProjectId>62</ProjectId>
        <LCAmountCurr>AED</LCAmountCurr>
        <LCAmount>367.25</LCAmount>
        <FCCurr>USD</FCCurr>
        <FCAmount>100</FCAmount>
        <ExchangeRate>3.67252</ExchangeRate>
        <ExpenseDate>2020-11-03T00:00:00+04:00</ExpenseDate>
        <ClaimItemNo>ITM-004</ClaimItemNo>
        <GLAccount>10000000</GLAccount>
        <VatRate>5%</VatRate>
        <VatBaseAmount>349.76</VatBaseAmount>
        <VatAmount>17.49</VatAmount>
        <ClaimType>LOB</ClaimType>
        <ForPayment>357.25</ForPayment>
        <ForDeduction>0.00</ForDeduction>
        <EmpCode>2019-1194</EmpCode>
    </ClaimExpense>
    <ClaimExpense>
        <ClaimNo>3003-LOB-0003</ClaimNo>
        <Office>3003</Office>
        <BranchId>1</BranchId>
        <CostCenterId>35</CostCenterId>
        <ServiceLineId>14</ServiceLineId>
        <ProjectId>62</ProjectId>
        <LCAmountCurr>AED</LCAmountCurr>
        <LCAmount>90.00</LCAmount>
        <FCCurr>AED</FCCurr>
        <FCAmount>90</FCAmount>
        <ExchangeRate>1</ExchangeRate>
        <ExpenseDate>2020-11-03T00:00:00+04:00</ExpenseDate>
        <ClaimItemNo>ITM-005</ClaimItemNo>
        <GLAccount>10000000</GLAccount>
        <VatRate/>
        <ClaimType>LOB</ClaimType>
        <ForPayment>357.25</ForPayment>
        <ForDeduction>0.00</ForDeduction>
        <EmpCode>2019-1194</EmpCode>
    </ClaimExpense>
</NewDataSet>');

select c.value('(ClaimNo/text())[1]', 'VARCHAR(20)') as ClaimNo
  -- everything in between with proper data types
  , c.value('(EmpCode/text())[1]', 'VARCHAR(10)') as EmpCode
from tbl cross apply xmldata.nodes('/NewDataSet/ClaimExpense') t(c);

【讨论】:

  • 太棒了。但是如果我想全选 * 而不是单个列,那么我放 * 但不起作用
  • @Stacky 也不会。 XML 不是表,它是 XML。 需要定义所需的列和数据。
【解决方案2】:

正如我在 cmets 中提到的,您需要使用节点的名称;您的 XML 没有节点“行”,因此 SQL Server 当然不会找到任何数据。我还建议使用text() 函数,因为它的效率要高得多。例如:

SELECT NDS.CE.value('(ClaimNo/text())[1]','int') AS ClaimNo
FROM @XML.nodes('NewDataSet/ClaimExpense') NDS(CE);

【讨论】:

    猜你喜欢
    • 2022-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 2018-01-26
    • 2012-08-11
    相关资源
    最近更新 更多