IN et NOT IN pour la colonne XML

8

J'ai une table avec une colonne xml. Xml est similaire à

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

Maintenant, sous la requête, retournez la colonne sl_no et myxmlcolumn des lignes contenant une colonne xml ayant des valeurs 'abc' ou 'xyz' dans le nœud 'user' (). En dessous de la requête, j'utilise une option similaire à IN de 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

Je veux un type de requête similaire qui fait le même travail que sql 'NOT IN'. C'est dans mon cas, je veux des lignes n'ayant pas de valeurs 'abc' ou 'xyz' dans le nœud 'user' () dans la colonne xml. Alors s'il vous plaît, aidez-moi à ce sujet.

Chercheur informatique
la source

Réponses:

12

La méthode exist () (type de données xml) renvoie a bit.
1si au moins un nœud est trouvé et 0si aucun nœud n'est trouvé (jeu de résultats vide).

Pour obtenir les lignes où ni l'une ABCni l'autre XYZn'existe, il suffit de comparer le résultat de existavec 0.

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

Votre requête FLWOR peut être réécrite à l'aide d'un prédicat sur le nœud utilisateur à la place,

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

Et pour la INversion de la requête, vous vérifiez si existrenvoie à la 1place.

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