Sql server 如果存在子元素并基于子元素+SQL Server的值,则选择XML节点

Sql server 如果存在子元素并基于子元素+SQL Server的值,则选择XML节点,sql-server,xml,xpath,Sql Server,Xml,Xpath,我只想提取那些具有特定子节点且该子节点应具有值的节点。 例: 查看下面的解决方案。它正在使用XQuery及其FLWOR表达式 SQL 查看下面的解决方案。它正在使用XQuery及其FLWOR表达式 SQL 这也应该奏效。删除没有Rindicator或Rindicator的值不同于1的节点,如预期输出所示 update @XML set data.modify('delete //Version[not(Rindicator[.="1"])]') 这也应该奏效。删除没有Rindicator或Ri

我只想提取那些具有特定子节点且该子节点应具有值的节点。 例:


查看下面的解决方案。它正在使用XQuery及其FLWOR表达式

SQL


查看下面的解决方案。它正在使用XQuery及其FLWOR表达式

SQL


这也应该奏效。删除没有Rindicator或Rindicator的值不同于1的节点,如预期输出所示

update @XML set data.modify('delete //Version[not(Rindicator[.="1"])]')

这也应该奏效。删除没有Rindicator或Rindicator的值不同于1的节点,如预期输出所示

update @XML set data.modify('delete //Version[not(Rindicator[.="1"])]')

谢谢你。请您指出我的做法中遗漏了什么或做错了什么。1我不明白您为什么尝试使用通配符名称空间前缀。2您可以尝试使用与我对Rindicator元素相同的构造。我使用通配符名称空间前缀,因为我在xml中有多个名称空间。您需要了解如何在提问时提供最小的可复制示例。名称空间是其中的一部分。请您指出我的做法中遗漏了什么或做错了什么。1我不明白您为什么尝试使用通配符名称空间前缀。2您可以尝试使用与我对Rindicator元素相同的构造。我使用通配符名称空间前缀,因为我在xml中有多个名称空间。您需要了解如何在提问时提供最小的可复制示例。名称空间是它的一部分。您可以对变量的Rindicator相等性进行否定。这将包括缺少Rindicator元素的版本节点:.modify'delete/*:Report/*:Version[not*:Rindicator=sql:variable@RindVal]';谢谢你的工作。如果你可以把它作为答案,我可以把它标记为…@BumbleBee…:,你可以把答案贴在名称空间通配符下面,以供参考。它对遇到类似问题的任何人都非常有用。您可以否定变量的Rindicator等式。这将包括缺少Rindicator元素的版本节点:.modify'delete/*:Report/*:Version[not*:Rindicator=sql:variable@RindVal]';谢谢你的工作。如果你可以把它作为答案,我可以把它标记为…@BumbleBee…:,你可以把答案贴在名称空间通配符下面,以供参考。它对遇到类似问题的任何人都非常有用。
DECLARE @RindVal varchar(2) = '1'
 UPDATE #TempTable
 SET xmlDoc.modify('delete /*:Report/*:Version[*:Rindicator != sql:variable("@RindVal")]');
-- DDL and sample data population. start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, xmlDoc XML);
INSERT INTO @tbl (xmlDoc) VALUES
(N'<Report>
    <Version>
        <RecordId>1</RecordId>
        <Note>abcd</Note>
    </Version>
    <Version>
        <RecordId>2</RecordId>
        <Note>efgh</Note>
        <Rindicator>1</Rindicator>
    </Version>
    <Version>
        <RecordId>3</RecordId>
        <Note>ijkl</Note>
        <Rindicator>1</Rindicator>
    </Version>
    <Version>
        <RecordId>4</RecordId>
        <Note>ijkl</Note>
        <Rindicator>0</Rindicator>
    </Version>
</Report>');
-- DDL and sample data population. end

-- before
SELECT * FROM @tbl;

DECLARE @RindVal char(1) = '1';

UPDATE @tbl
SET xmlDoc = xmlDoc.query('<Report>
 {
     for $x in /Report/Version[(Rindicator/text())[1] eq sql:variable("@RindVal")]
     return $x
 }
 </Report>');

 -- after
 SELECT * FROM @tbl;
update @XML set data.modify('delete //Version[not(Rindicator[.="1"])]')