IN dan NOT IN untuk kolom XML

8

Saya punya tabel dengan kolom xml. Xml mirip dengan

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

Sekarang di bawah query, kembalikan kolom sl_no dan myxmlcolumn dari baris yang berisi kolom xml yang memiliki nilai 'abc' atau 'xyz' di node 'user' (). Di bawah query saya menggunakan mirip dengan opsi IN 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

Saya ingin jenis query serupa yang berfungsi sama dengan sql 'NOT IN'. Itu dalam kasus saya saya ingin baris tidak memiliki nilai 'abc' atau 'xyz' di node 'user' () di kolom xml. Jadi tolong bantu saya dalam hal ini.

Peneliti IT
sumber

Jawaban:

12

Metode exist () (xml Tipe Data) mengembalikan a bit.
1jika setidaknya satu node ditemukan dan 0jika tidak ada node yang ditemukan (set hasil kosong).

Untuk mendapatkan baris di mana tidak ada ABCatau XYZada, Anda hanya perlu membandingkan hasil existdengan 0.

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

Permintaan FLWOR Anda dapat ditulis ulang menggunakan predikat pada simpul pengguna sebagai gantinya,

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

Dan untuk INversi kueri Anda memeriksa apakah existkembali 1sebagai gantinya.

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