获取所有行,即使节点并不总是存在
Get all rows, even when node is not always present
我有数千个 xml 文件可以从中获取数据。
为此,我使用了交叉应用方法。
但问题是,某些节点并不总是存在于 xml 文件中。
在我的示例中,这是节点 'valueX'(在产品节点内)。而这个节点只存在于最后一个人身上。
<invoice>
<person>
<name>John</name>
<product>
<id>abc</id>
<price>100</price>
</product>
<product>
<id>def</id>
<price>99</price>
</product>
</person>
<person>
<name>Mary</name>
<product>
<id>abc</id>
<price>200</price>
</product>
</person>
<person>
<name>Peter</name>
<product>
<id>abc</id>
<price>300</price>
</product>
</person>
<person>
<name>Sue</name>
<product>
<id>abc</id>
<price>400</price>
<valueX>
<name>test</name>
</valueX>
</product>
</person>
</invoice>
如果我现在使用 'valueX' 节点查询带有交叉应用的 xml 文件,我只会得到包含该节点的一条记录。
declare @tab table (
id int
, xmlData xml
)
declare @xml nvarchar(max)
set @xml = '
<invoice>
<person>
<name>John</name>
<product>
<id>abc</id>
<price>100</price>
</product>
<product>
<id>def</id>
<price>99</price>
</product>
</person>
<person>
<name>Mary</name>
<product>
<id>abc</id>
<price>200</price>
</product>
</person>
<person>
<name>Peter</name>
<product>
<id>abc</id>
<price>300</price>
</product>
</person>
<person>
<name>Sue</name>
<product>
<id>abc</id>
<price>400</price>
<valueX>
<name>test</name>
</valueX>
</product>
</person>
</invoice>
'
insert into @tab (id, xmlData)
values (
1
, @xml
)
select t.id
, Person.ref.value('name[1]','nvarchar(255)') as PersonName
, Product.ref.value('id[1]','nvarchar(3)') as ProductID
, Product.ref.value('price[1]','int') as ProductPrice
, ValueX.ref.value('name[1]','nvarchar(255)') as ValueXName
from @tab as t
cross apply t.xmlData.nodes('invoice/person') Person(ref)
cross apply Person.ref.nodes('product') Product(ref)
cross apply Product.ref.nodes('valueX') ValueX(ref)
但即使节点不存在,我也需要拥有所有记录。
我怎样才能做到这一点?
把你的最后一部分改成
from @tab as t
outer apply t.xmlData.nodes('invoice/person') Person(ref)
outer apply Person.ref.nodes('product') Product(ref)
outer apply Product.ref.nodes('valueX') ValueX(ref)
CROSS APPLY
类似于 INNER JOIN
而 OUTER APPLY
类似于 LEFT JOIN
我有数千个 xml 文件可以从中获取数据。 为此,我使用了交叉应用方法。
但问题是,某些节点并不总是存在于 xml 文件中。 在我的示例中,这是节点 'valueX'(在产品节点内)。而这个节点只存在于最后一个人身上。
<invoice>
<person>
<name>John</name>
<product>
<id>abc</id>
<price>100</price>
</product>
<product>
<id>def</id>
<price>99</price>
</product>
</person>
<person>
<name>Mary</name>
<product>
<id>abc</id>
<price>200</price>
</product>
</person>
<person>
<name>Peter</name>
<product>
<id>abc</id>
<price>300</price>
</product>
</person>
<person>
<name>Sue</name>
<product>
<id>abc</id>
<price>400</price>
<valueX>
<name>test</name>
</valueX>
</product>
</person>
</invoice>
如果我现在使用 'valueX' 节点查询带有交叉应用的 xml 文件,我只会得到包含该节点的一条记录。
declare @tab table (
id int
, xmlData xml
)
declare @xml nvarchar(max)
set @xml = '
<invoice>
<person>
<name>John</name>
<product>
<id>abc</id>
<price>100</price>
</product>
<product>
<id>def</id>
<price>99</price>
</product>
</person>
<person>
<name>Mary</name>
<product>
<id>abc</id>
<price>200</price>
</product>
</person>
<person>
<name>Peter</name>
<product>
<id>abc</id>
<price>300</price>
</product>
</person>
<person>
<name>Sue</name>
<product>
<id>abc</id>
<price>400</price>
<valueX>
<name>test</name>
</valueX>
</product>
</person>
</invoice>
'
insert into @tab (id, xmlData)
values (
1
, @xml
)
select t.id
, Person.ref.value('name[1]','nvarchar(255)') as PersonName
, Product.ref.value('id[1]','nvarchar(3)') as ProductID
, Product.ref.value('price[1]','int') as ProductPrice
, ValueX.ref.value('name[1]','nvarchar(255)') as ValueXName
from @tab as t
cross apply t.xmlData.nodes('invoice/person') Person(ref)
cross apply Person.ref.nodes('product') Product(ref)
cross apply Product.ref.nodes('valueX') ValueX(ref)
但即使节点不存在,我也需要拥有所有记录。
我怎样才能做到这一点?
把你的最后一部分改成
from @tab as t
outer apply t.xmlData.nodes('invoice/person') Person(ref)
outer apply Person.ref.nodes('product') Product(ref)
outer apply Product.ref.nodes('valueX') ValueX(ref)
CROSS APPLY
类似于 INNER JOIN
而 OUTER APPLY
类似于 LEFT JOIN