IN und NOT IN für XML-Spalte

8

Ich habe eine Tabelle mit einer XML-Spalte. Xml ist ähnlich wie

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

Jetzt unter der Abfrage geben Sie die Spalte sl_no und die Spalte myxml mit Zeilen zurück, die die XML-Spalte mit den Werten 'abc' oder 'xyz' im Knoten 'user' () enthalten. Unter der Abfrage verwende ich eine ähnliche IN-Option wie 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

Ich möchte eine ähnliche Art von Abfrage, die genauso funktioniert wie SQL 'NOT IN'. Das heißt, in meinem Fall möchte ich Zeilen ohne Werte 'abc' oder 'xyz' im Knoten 'user' () in der XML-Spalte. Bitte helfen Sie mir dabei.

IT-Forscher
quelle

Antworten:

12

Die exist () -Methode (xml-Datentyp) gibt a zurück bit.
1wenn mindestens ein Knoten gefunden wird und 0wenn keine Knoten gefunden werden (leere Ergebnismenge).

Um die Zeilen zu erhalten, in denen keine ABCoder keine XYZvorhanden sind, müssen Sie nur das Ergebnis von existmit vergleichen 0.

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

Ihre FLWOR-Abfrage kann stattdessen mit einem Prädikat auf dem Benutzerknoten neu geschrieben werden.

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

Und für die INVersion der Abfrage überprüfen Sie , ob existRenditen 1statt.

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