IN e NOT IN per la colonna XML


8

Ho una tabella con una colonna XML. Xml è simile 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>

Ora sotto query return sl_no column e myxmlcolumn di righe contenenti colonna xml con valori 'abc' o 'xyz' nel nodo 'user' (). Sotto la query sto usando un'opzione simile a IN di 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

Voglio un tipo di query simile che funzioni allo stesso modo di sql "NOT IN". Cioè nel mio caso voglio che le righe non abbiano valori 'abc' o 'xyz' nel nodo 'user' () nella colonna xml. Quindi per favore aiutatemi su questo.

Risposte:


12

Il metodo exist () (tipo di dati xml) restituisce a bit.
1se viene trovato almeno un nodo e 0se non viene trovato alcun nodo (set di risultati vuoto).

Per ottenere le righe in cui nessuna delle due ABCo XYZesiste, devi solo confrontare il risultato di existcon 0.

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

È possibile riscrivere la query FLWOR utilizzando un predicato sul nodo utente,

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

E per la INversione della query controlli se existrestituisce 1invece.

select Sl_no,
       myxmlcolumn
from mytable
where myxmlcolumn.exist('/Root/Row/user[fn:upper-case(text()[1]) = ("ABC", "XYZ")]') = 1
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.