我有一张合约表。有几列,最后是一个代表整个合同的XML列。合同内部是项目(1个或更多),每个项目内部有1个或更多行。我需要能够选择所有的行和它们所在的项目,但我现在通过我的示例查询获得了奇怪的结果。
以下是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"><BOM1></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"><BOM2></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>
以下是我的示例查询:
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)
结果如下:
QGPET0000000218 0.080 Aluminum 2ft x 4ft <BOM1>
QGPET0000000218 #8X8SPOOL <BOM1>
QGPET0000000218 0.080 Aluminum 2ft x 4ft <BOM2>
QGPET0000000218 #8X8SPOOL <BOM2>
问题是“0.080铝2英尺x 4英尺”仅在“BOM1”上,“#8X8SPOOL”仅在“BOM2”上,因此结果中应该只有2行。请帮忙,谢谢!
答案 0 :(得分:3)
这应该有效。请注意,第二个CROSS APPLY链接到第一个(Proj.ProjName.nodes()
而不是CM.FullContract.nodes()
),而不是将XML重新粉碎成一个全新的表。这样做可以使您的子数据与正确的项目名称相关联:
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)