Coluna IN e NOT IN para XML

8

Eu tenho uma tabela com uma coluna xml. Xml é semelhante a

<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>

Agora, abaixo da consulta, retorne a coluna sl_no e a coluna myxml das linhas que contêm a coluna xml com os valores 'abc' ou 'xyz' no nó 'user' (). Abaixo da consulta, estou usando a opção IN do sql.

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

Eu quero um tipo semelhante de consulta que faz o mesmo trabalho que o sql 'NOT IN'. Ou seja, no meu caso, quero que as linhas não tenham valores 'abc' ou 'xyz' no nó 'user' () na coluna xml. Então, por favor me ajude nisso.

Pesquisador de TI
fonte

Respostas:

12

O método exist () (xml Data Type) retorna a bit.
1se pelo menos um nó for encontrado e 0se nenhum nó for encontrado (conjunto de resultados vazio).

Para obter as linhas onde não ABCou XYZexiste você só tem que comparar o resultado de existcom 0.

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

Sua consulta FLWOR pode ser reescrita usando um predicado no nó do usuário.

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

E para a INversão da consulta, verifique se existretorna 1.

select Sl_no,
       myxmlcolumn
from mytable
where myxmlcolumn.exist('/Root/Row/user[fn:upper-case(text()[1]) = ("ABC", "XYZ")]') = 1
Mikael Eriksson
fonte