简体   繁体   English

SQL XQuery和Cross Apply问题......结果中的行太多了

[英]SQL XQuery and Cross Apply problems…too many rows in results

I have a table of contracts. 我有一份合同表。 There are several columns and finally an XML column representing the whole contract. 有几列,最后是代表整个合同的XML列。 Inside the contract are projects (1 or more) and inside each project are 1 or more lines. 合同中包含项目(1个或更多),每个项目中包含1条或更多行。 I need to be able to select all of the lines and the projects they are on, but I'm getting odd results right now with my sample query. 我需要能够选择所有的行和它们所在的项目,但是现在我的样本查询得到了奇怪的结果。

Here is a sample of the XML: 以下是XML的示例:

<ZEstimateContract xmlns="http://schemas.datacontract.org/2004/07/Zeller.Gp" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" z:Id="i1">
  <Name xmlns="http://schemas.datacontract.org/2004/07/Zynergy">QGPET0000000218</Name>
  <_projects>
    <ZEstimateProject z:Id="i9">
      <Name xmlns="http://schemas.datacontract.org/2004/07/Zynergy">&lt;BOM1&gt;</Name>
      <Parent i:nil="true" />
      <Quantity>1</Quantity>
      <_lines>
        <ZEstimateLine z:Id="i40">
          <Name xmlns="http://schemas.datacontract.org/2004/07/Zynergy">0.080 Aluminum 2ft x 4ft</Name>
          <_lines />
        </ZEstimateLine>
      </_lines>
      <_projects />
    </ZEstimateProject>
    <ZEstimateProject z:Id="i97">
      <Name xmlns="http://schemas.datacontract.org/2004/07/Zynergy">&lt;BOM2&gt;</Name>
      <Parent i:nil="true" />
      <Quantity>1</Quantity>      
      <_lines>
        <ZEstimateLine z:Id="i113">          
          <Name xmlns="http://schemas.datacontract.org/2004/07/Zynergy">#8X8SPOOL</Name>
        </ZEstimateLine>
      <_projects />
    </ZEstimateProject>
  </_projects>
</ZEstimateContract>

And here is my sample query: 这是我的示例查询:

WITH XMLNAMESPACES('http://schemas.datacontract.org/2004/07/Zeller.Gp' AS ZC, 
    'http://schemas.datacontract.org/2004/07/Zynergy' AS ZYN)

SELECT Contract, LineName.value('.', 'varchar(50)') as LineItemName, ProjName.value('.', 'varchar(50)') as ProjectName
FROM dbo.tblContractMaster AS CM 
CROSS APPLY CM.FullContract.nodes('/ZC:ZEstimateContract/ZC:_projects/ZC:ZEstimateProject/ZYN:Name') as Proj(ProjName)
CROSS APPLY CM.FullContract.nodes('/ZC:ZEstimateContract/ZC:_projects/ZC:ZEstimateProject/ZC:_lines/ZC:ZEstimateLine/ZYN:Name') as Line(LineName)

The results are: 结果是:

QGPET0000000218    0.080 Aluminum 2ft x 4ft          <BOM1>
QGPET0000000218    #8X8SPOOL                         <BOM1>
QGPET0000000218    0.080 Aluminum 2ft x 4ft          <BOM2>
QGPET0000000218    #8X8SPOOL                         <BOM2>

The problem is that "0.080 Aluminum 2ft x 4ft" is only on "BOM1" and "#8X8SPOOL" is only on "BOM2", so there should only be 2 rows in the results. 问题是“0.080铝2英尺x 4英尺”仅在“BOM1”上,“#8X8SPOOL”仅在“BOM2”上,因此结果中应该只有2行。 Please help, thanks! 请帮忙,谢谢!

This ought to work. 这应该工作。 Note that the second CROSS APPLY is chained to the first one ( Proj.ProjName.nodes() as opposed to CM.FullContract.nodes() ), rather than re-shredding your XML into an entirely new table. 请注意,第二个CROSS APPLY链接到第一个( Proj.ProjName.nodes()而不是CM.FullContract.nodes() ),而不是将XML重新粉碎成一个全新的表。 Doing this is what keeps your child data associated with the correct project name: 这样做可以使您的子数据与正确的项目名称相关联:

WITH XMLNAMESPACES('http://schemas.datacontract.org/2004/07/Zeller.Gp' AS ZC, 
    'http://schemas.datacontract.org/2004/07/Zynergy' AS ZYN)

SELECT Contract, LineName.value('.', 'varchar(50)') as LineItemName, ProjName.value('.', 'varchar(50)') as ProjectName
FROM @contract AS CM 
CROSS APPLY CM.FullContract.nodes('/ZC:ZEstimateContract/ZC:_projects/ZC:ZEstimateProject/ZYN:Name') as Proj(ProjName)
CROSS APPLY Proj.ProjName.nodes('../ZC:_lines/ZC:ZEstimateLine/ZYN:Name') as Line(LineName)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM