如何为多个值过滤xml元素

时间:2019-02-01 21:00:18

标签: sql-server xml

XML使用xml数据类型存储在SQL Server的表中。

CREATE TABLE MyTable(
 i int primary key,   
XmlField xml NULL
)
insert into  MyTable(i, xmlField)  
values(1, N'<root>  
<Area1>  
 <Parent> 
     <Name>ParentJay</Name>
 <Spouse>Janice</Spouse>
     <child>John
        <grandchild>Kate</grandchild>
        <grandchild>Moss</grandchild>
        <grandchild>Ruby</grandchild>
        <grandchild>Violet</grandchild>
</child>
</Parent>
<Parent> 
<Name>ParentMark</Name>
<Spouse>May</Spouse>
<child>Mary
        <grandchild>Violet</grandchild>
        <grandchild>Kate</grandchild>
        <grandchild>jubi</grandchild>
</child>
</Parent>
<Parent> 
<Name>ParentJoe</Name>
<Spouse>kim</Spouse>
<child>Kelly
        <grandchild>Moss</grandchild>
        <grandchild>Kate</grandchild>
</child>
</Parent>
<Parent> 
<Name>ParentMike</Name>
<Spouse>Mia</Spouse>
<child>Mary
        <grandchild>Jeff</grandchild>
        <grandchild>jubi</grandchild>
        <grandchild>Violet</grandchild>
</child>
</Parent>
</Area1>
</root>')

问题:获取所有具有孙代名称Kate和Moss的子节点

我有一个查询要让一个孙子凯特(Kate)过滤子元素。

有没有一种方法可以使用和/或查询中的多个孙子名称(Kate和Moss)进行过滤。

declare @v varchar(20) 
set @v='Kate'
SELECT  
child = x.value('local-name(..)', 'varchar(50)'),
value = x.value('(..)', 'varchar(50)') 
FROM   MyTable
CROSS APPLY XmlField.nodes('/root/Area1/Parent/child/*[contains((.),sql:variable("@v"))] ' ) as T2(x) 

Result
child   value
child   John    KateMossRubyViolet
child   Mary    VioletKatejubi
child   Kelly    MossKate


Result looking for:
child   value
child   John    KateMossRubyViolet
child   Kelly    MossKate

1 个答案:

答案 0 :(得分:0)

我认为,您已将过滤谓词放置在一个更深的层次上...

您可以使用这样的查询

SELECT grCh.query('.')
FROM mytable
CROSS APPLY xmlField.nodes('/root/Area1/Parent[child[grandchild="Kate" and grandchild="Moss"]]') A(grCh);

您可以将其理解为:潜入根-> Area1->父级。在这个级别上,我们需要一个谓词。这里我们说:有一个节点<child>,其中(多了一个谓语)有一个名为凯特和一个孙子莫斯(你可以使用or为好)

您可以引入值sql:variable()或{与{1}}如果你不想字面上硬编码他们。

希望这对您有帮助...