SQL Server XML筛选器

问题描述

我有一个XML数据,例如:

<EmployeeDetails>
  <BusinessEntityID>3</BusinessEntityID>
  <NationalIDNumber>509647174</NationalIDNumber>
  <JobTitle>Engineering Manager</JobTitle>
  <BirthDate>1974-11-12</BirthDate>
  <MaritalStatus>M</MaritalStatus>
  <Gender>M</Gender>
  <StoreDetail>
    <Store>
      <AnnualSales>800000</AnnualSales>
      <AnnualRevenue>80000</AnnualRevenue>
      <BankName>Guardian Bank</BankName>
      <BusinessType>BM</BusinessType>
      <YearOpened>1987</YearOpened>
      <Specialty>Touring</Specialty>
      <SquareFeet>21000</SquareFeet>
    </Store>
    <Store>
      <AnnualSales>300000</AnnualSales>
      <AnnualRevenue>30000</AnnualRevenue>
      <BankName>International Bank</BankName>
      <BusinessType>BM</BusinessType>
      <YearOpened>1982</YearOpened>
      <Specialty>Road</Specialty>
      <SquareFeet>9000</SquareFeet>
    </Store>
  </StoreDetail>
</EmployeeDetails>

作为一个例子,我想按照“ SquareFeet> 10000”和我想要得到的结果进行过滤

<EmployeeDetails>
  <BusinessEntityID>3</BusinessEntityID>
  <NationalIDNumber>509647174</NationalIDNumber>
  <JobTitle>Engineering Manager</JobTitle>
  <BirthDate>1974-11-12</BirthDate>
  <MaritalStatus>M</MaritalStatus>
  <Gender>M</Gender>
  <StoreDetail>
    <Store>
      <AnnualSales>800000</AnnualSales>
      <AnnualRevenue>80000</AnnualRevenue>
      <BankName>Guardian Bank</BankName>
      <BusinessType>BM</BusinessType>
      <YearOpened>1987</YearOpened>
      <Specialty>Touring</Specialty>
      <SquareFeet>21000</SquareFeet>
    </Store>
  </StoreDetail>
</EmployeeDetails>

我可以使用sql Server执行此操作吗?我想要得到的结果仍然是XML数据。

解决方法

这可以按照以下步骤完成

select * into #tmp from YourTable

update #tmp
set xmldata.modify('
  delete (/EmployeeDetails/StoreDetail/Store[SquareFeet <= 10000])[1]
')

select * from #tmp

drop table #tmp
,

SQL Server XQuery及其FLWOR表达式可轻松实现您所需的功能。

T-SQL

DECLARE @xml XML =
N'<EmployeeDetails>
    <BusinessEntityID>3</BusinessEntityID>
    <NationalIDNumber>509647174</NationalIDNumber>
    <JobTitle>Engineering Manager</JobTitle>
    <BirthDate>1974-11-12</BirthDate>
    <MaritalStatus>M</MaritalStatus>
    <Gender>M</Gender>
    <StoreDetail>
        <Store>
            <AnnualSales>800000</AnnualSales>
            <AnnualRevenue>80000</AnnualRevenue>
            <BankName>Guardian Bank</BankName>
            <BusinessType>BM</BusinessType>
            <YearOpened>1987</YearOpened>
            <Specialty>Touring</Specialty>
            <SquareFeet>21000</SquareFeet>
        </Store>
        <Store>
            <AnnualSales>300000</AnnualSales>
            <AnnualRevenue>30000</AnnualRevenue>
            <BankName>International Bank</BankName>
            <BusinessType>BM</BusinessType>
            <YearOpened>1982</YearOpened>
            <Specialty>Road</Specialty>
            <SquareFeet>9000</SquareFeet>
        </Store>
    </StoreDetail>
</EmployeeDetails>';

SELECT @xml.query('<EmployeeDetails>
{
for $x in /EmployeeDetails/*
return if (local-name($x) ne "StoreDetail") then $x
        else 
            <StoreDetail>
            {
            for $y in $x/Store
            where $y/SquareFeet/text() > 10000
            return $y
            }
            </StoreDetail>
}
</EmployeeDetails>');

输出

<EmployeeDetails>
  <BusinessEntityID>3</BusinessEntityID>
  <NationalIDNumber>509647174</NationalIDNumber>
  <JobTitle>Engineering Manager</JobTitle>
  <BirthDate>1974-11-12</BirthDate>
  <MaritalStatus>M</MaritalStatus>
  <Gender>M</Gender>
  <StoreDetail>
    <Store>
      <AnnualSales>800000</AnnualSales>
      <AnnualRevenue>80000</AnnualRevenue>
      <BankName>Guardian Bank</BankName>
      <BusinessType>BM</BusinessType>
      <YearOpened>1987</YearOpened>
      <Specialty>Touring</Specialty>
      <SquareFeet>21000</SquareFeet>
    </Store>
  </StoreDetail>
</EmployeeDetails>