IN и NOT IN для столбца XML

8

У меня есть таблица со столбцом XML. Xml похож на

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

Теперь под запросом возвращаем столбец sl_no и myxmlcolumn строк, содержащих столбец xml со значениями 'abc' или 'xyz' в узле 'user' (). Ниже запроса я использую аналогичную 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

Я хочу, чтобы запрос аналогичного типа выполнялся так же, как и sql NOT IN. То есть в моем случае я хочу, чтобы строки, не имеющие значений 'abc' или 'xyz' в узле 'user' () в столбце xml. Поэтому, пожалуйста, помогите мне в этом.

IT исследователь
источник

Ответы:

12

Метод exist () (тип данных xml) возвращает a bit.
1если найден хотя бы один узел и 0не найдено ни одного узла (пустой набор результатов).

Чтобы получить строки, где их нет ABCили они XYZсуществуют, вам просто нужно сравнить результат existс 0.

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

Ваш запрос FLWOR может быть переписан с использованием предиката на пользовательском узле,

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

И для INверсии запроса вы проверяете, existвозвращает ли 1вместо этого.

select Sl_no,
       myxmlcolumn
from mytable
where myxmlcolumn.exist('/Root/Row/user[fn:upper-case(text()[1]) = ("ABC", "XYZ")]') = 1
Микаэль Эрикссон
источник