SQL-запрос для итерации в узлах XML для проверки значения и возврата записи

#sql #xml #db2 #xquery-sql

#sql #xml #db2 #xquery-sql

Вопрос:

Одна из моих таблиц базы данных содержит несколько записей. В каждой записи есть столбец, в котором хранится XML следующего типа . Мне нужно написать запрос, который должен извлекать записи, в которых внутри родительского узла, если какой-либо из подузлов содержит только значение 0 полностью. В этом примере четвертый узел содержит все 0. Это удовлетворяет условию, и запись должна быть извлечена. Могу ли я узнать, как записать это условие в SQL для извлечения таким образом?

Примечание: родительский узел может содержать несколько подузлов.

XML:

         <videoDetails>
            <video>
                <V1>
                    <display>0</display>
                </V1>
                <V2>
                    <display>0</display>
                </V2>
                <V3>
                    <display>0</display>
                </V3>
                <V4>
                    <display>0</display>
                </V4>
                <V5>
                    <display>1</display>
                </V5>
            </video>
            <video>                 
                <V1>
                    <display>0</display>
                </V1>
                <V2>
                    <display>0</display>
                </V2>
                <V3>
                    <display>1</display>
                </V3>
                <V4>
                    <display>0</display>
                </V4>
                <V5>
                    <display>0</display>
                </V5>
            </video>
            <video>                 
                <V1>
                    <display>0</display>
                </V1>
                <V2>
                    <display>1</display>
                </V2>
                <V3>
                    <display>0</display>
                </V3>
                <V4>
                    <display>0</display>
                </V4>
                <V5>
                    <display>1</display>
                </V5>
            </video>
            <video>                 
                <V1>
                    <display>0</display>
                </V1>
                <V2>
                    <display>0</display>
                </V2>
                <V3>
                    <display>0</display>
                </V3>
                <V4>
                    <display>0</display>
                </V4>
                <V5>
                    <display>0</display>
                </V5>
            </video>
        </videoDetails>
         
 

Я попытался использовать что-то вроде NOT xmlexists(‘$ N /../.. / ../videoDetails/video[1] /* [display= 1]’, передавая USER_VIDEO_XML как «N») . Это работает только тогда, когда XML содержит один узел, который имеет все 0 и не работает с несколькими узлами.

Запросите ваши ценные входные данные.

Комментарии:

1. Поддержка XML сильно зависит от поставщика — поэтому, пожалуйста, добавьте тег, чтобы указать, используете ли вы mysql , postgresql , sql-server , oracle или db2 — или что-то совсем другое.

2. ваш XPath заставляет его просматривать только 1-й узел <video>. .../video[1]... . это [1] заставляет его игнорировать все остальные. Вы пробовали без указания позиции массива. '$N/../../../videoDetails/video/*[display=1]' ?

Ответ №1:

Используйте следующий запрос:

 SELECT 1
FROM MY_TAB T
WHERE XMLCAST(XMLQUERY
(
'
let $d :=
for $v in $doc/videoDetails/video
  return fn:exists($v/*[display != 0])
return fn:exists($d[. = fn:false()])
' PASSING T.DOC AS "doc" 
) AS INT) = 1
 

for Цикл перебирает все video подузлы и возвращает следующую последовательность в $ d для вашего данного примера:
(true, true, true, false)
4 video подузла. Первые 3 из них содержат display !=0 , а 4-й — нет. Предложение return outer возвращает true, если приведенная выше последовательность содержит false значение. Вы можете поиграть с образцами данных, проверяя результат по следующей ссылке db<>fiddle.