Выберите узел XML, если дочерний элемент существует, и на основе значения дочернего элемента + SQL Server - PullRequest
0 голосов
/ 07 апреля 2020

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

   xmlDoc = <Report>
      <Version>
        <RecordId>1</RecordId>
        <Note>abcd</Note>
      </Version>
      <Version>
        <RecordId>2</RecordId>
        <Note>efgh</Note>
        <Rindicator>1</Rindicator>
      </Version>
    <Version>
        <RecordId>3</RecordId>
        <Note>ijkl</Note>
      <Rindicator>1</Rindicator>
      </Version>
    <Version>
        <RecordId>4</RecordId>
        <Note>ijkl</Note>
      <Rindicator>0</Rindicator>
      </Version>
    </Report>

Результат должен быть

   <Report>
          <Version>
            <RecordId>2</RecordId>
            <Note>efgh</Note>
            <Rindicator>1</Rindicator>
          </Version>
        <Version>
            <RecordId>3</RecordId>
            <Note>ijkl</Note>
          <Rindicator>1</Rindicator>
          </Version>
        </Report>

Я пробовал следующее, но не получил ожидаемых результатов.

DECLARE @RindVal varchar(2) = '1'
 UPDATE #TempTable
 SET xmlDoc.modify('delete /*:Report/*:Version[*:Rindicator != sql:variable("@RindVal")]');

Ответы [ 2 ]

1 голос
/ 07 апреля 2020

Это тоже должно работать. Удалите узлы без Rindicator или со значением Rindicator, отличным от 1 (как показано в ожидаемом выводе).

update @XML set data.modify('delete //Version[not(Rindicator[.="1"])]')
1 голос
/ 07 апреля 2020

Проверьте решение ниже. Он использует XQuery и его выражение FLWOR.

SQL

-- DDL and sample data population. start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, xmlDoc XML);
INSERT INTO @tbl (xmlDoc) VALUES
(N'<Report>
    <Version>
        <RecordId>1</RecordId>
        <Note>abcd</Note>
    </Version>
    <Version>
        <RecordId>2</RecordId>
        <Note>efgh</Note>
        <Rindicator>1</Rindicator>
    </Version>
    <Version>
        <RecordId>3</RecordId>
        <Note>ijkl</Note>
        <Rindicator>1</Rindicator>
    </Version>
    <Version>
        <RecordId>4</RecordId>
        <Note>ijkl</Note>
        <Rindicator>0</Rindicator>
    </Version>
</Report>');
-- DDL and sample data population. end

-- before
SELECT * FROM @tbl;

DECLARE @RindVal char(1) = '1';

UPDATE @tbl
SET xmlDoc = xmlDoc.query('<Report>
 {
     for $x in /Report/Version[(Rindicator/text())[1] eq sql:variable("@RindVal")]
     return $x
 }
 </Report>');

 -- after
 SELECT * FROM @tbl;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...