Dilip Mevada Ответов: 1

Как я могу получить список родительского узла в XML с помощью SQL server?


Всем Привет,
Предположим, у меня есть таблица с типом данных xml. Рассмотрим приведенное ниже значение как данные в xml.

<Books>
  <Book ID="BK1">
    <Pages>
      <Page ID="Home" />
      <Page ID="Index" />
      <Page ID="Introduction" />
    </Pages>
  </Book>
  <Book ID="BK2">
    <Pages>
      <Page ID="Home" />
      <Page ID="Introduction" />
    </Pages>
  </Book>
  <Book ID="BK3">
    <Pages>
      <Page ID="Home" />
      <Page ID="Index" />
      <Page ID="Introduction" />
    </Pages>
  </Book>
  <Book ID="BK4">
    <Pages>
      <Page ID="Home" />
      <Page ID="Introduction" />
    </Pages>
  </Book>
</Books>





Мне нужен список идентификаторов книг, для которых отсутствует идентификатор страницы=индекс? (Например, в книгах ID=BK2 и ID=BK4 отсутствует идентификатор страницы=индекс?

Выход:
BookId
БК2
БК4

Что я уже пробовал:

SELECT Data.Col.value('(@ID)[1]','Varchar(100)') AS Books
FROM @x.nodes('/Books/Book/Pages/Page') AS Data(Col)
WHERE @x.exist('(/Books/Book/Pages/Page[@ID = sql:variable("@BookId")])') = 1

1 Ответов

Рейтинг:
12

Richard Deeming

Вам не нужно указывать полный путь в поле exist тест; вы просто хотите проверить против течения <Book> узел, а не весь документ целиком:

SELECT data.col.value('@ID', 'varchar(100)')
FROM @x.nodes('/Books/Book') As data(col)
WHERE data.col.exist('Pages/Page[@ID="Index"]') = 0;


Dilip Mevada

Спасибо за решение. Он прекрасно работает.

Можем ли мы получать данные непосредственно из таблицы SQL вместо узлов? Например. Книжный стол.
У меня есть дополнительное предложение where с таблицей SQL. Пожалуйста, предложите.

Richard Deeming

Если XML хранится в столбце вашей таблицы, то вам необходимо использовать CROSS APPLY для извлечения узлов:
Указание метода nodes() для столбца типа xml | метод nodes () (тип данных xml) - SQL Server | Microsoft Docs[^]

SELECT data.col.value('@ID', 'varchar(100)')
FROM YourTableWithAnXmlColumn As T
CROSS APPLY T.YourXmlColumn.nodes('/Books/Book') As data(col)
WHERE T.SomeColumn = @SomeValue
And data.col.exist('Pages/Page[@ID="Index"]') = 0;