XML 列的 IN 和 NOT IN

IT *_*her 8 xml sql-server sql-server-2008-r2 xquery

我有一个带有 xml 列的表。XML类似于

<Root>
  <Row>
    <user>abc</user>
    <Rowid>1</Rowid>
  </Row>
  <Row>
    <user>vf</user>
    <Rowid>2</Rowid>
  </Row>
  <Row>
    <user>ert</user>
    <Rowid>3</Rowid>
  </Row>
  <Maxrowid>3</Maxrowid>
</Root>
Run Code Online (Sandbox Code Playgroud)

现在下面的查询返回 sl_no 列和包含 xml 列的行的 myxmlcolumn 在节点 'user'() 中具有值 'abc' 或 'xyz'。下面的查询我使用类似于 sql 的 IN 选项。

SELECT
    [mytable].[Sl_no],
    [mytable].[myxmlcolumn]
    FROM [mydb].dbo.[mytable]
    WHERE
        [myxmlcolumn].exist('for $x in /Root/Row where (($x/user[fn:upper-case(.)=(''ABC'',''XYZ'')])) return $x') > 0
Run Code Online (Sandbox Code Playgroud)

我想要类似的查询,它与 sql 'NOT IN' 做同样的工作。在我的情况下,我希望在 xml 列中的节点“user”() 中没有值“abc”或“xyz”的行。所以请帮我解决这个问题。

Mik*_*son 12

存在()方法(XML数据类型)返回bit
1如果至少找到一个节点并且0没有找到节点(空结果集)。

为了让行,其中没有ABCXYZ存在的,你只需要比较的结果exist0

[myxmlcolumn].exist('for $x in /Root/Row 
                     where (($x/user[fn:upper-case(.)=(''ABC'',''XYZ'')])) 
                     return $x') = 0
Run Code Online (Sandbox Code Playgroud)

您可以使用用户节点上的谓词来重写您的 FLWOR 查询,

select Sl_no,
       myxmlcolumn
from mytable
where myxmlcolumn.exist('/Root/Row/user[fn:upper-case(text()[1]) = ("ABC", "XYZ")]') = 0
Run Code Online (Sandbox Code Playgroud)

对于IN查询的版本,您检查是否exist返回1

select Sl_no,
       myxmlcolumn
from mytable
where myxmlcolumn.exist('/Root/Row/user[fn:upper-case(text()[1]) = ("ABC", "XYZ")]') = 1
Run Code Online (Sandbox Code Playgroud)