Как получить все xml элементы из указанного раздела c столбца xml, используя xpath? - PullRequest
2 голосов
/ 06 марта 2020

У меня есть две таблицы tblUser и tblUserPermissions, и мне нужны все элементы разрешений из столбца xml ниже (XmlData) для каждого пользователя в tblUser. В каждом XmlData есть только один элемент идентификатора пользователя.

<User xmlns="">
  <userid>user1</userid>
  <permissions>
    <permission>per1</permission>
    <permission>per2</permission>
    <permission>per3</permission>
  </permissions>
  //Other elements here
</User>

Я пытаюсь выполнить этот запрос.

SELECT u.UserID, UserPermissions.perm.value('permission', 'varchar(50)')
FROM tblUserPermissions up WITH (NOLOCK)
INNER JOIN tblUser u ON u.UserID = up.XmlData.value('(/User/userid)[1]', 'int')
cross apply up.XmlData.nodes('/User/permissions') AS UserPermissions (perm)

Как получить результат, как показано ниже?

UserID | Permission

user1 | per1
user1 | per2
user1 | per3
user2 | per1
user2 | per2
user3 | per1
user3 | per2
user3 | per3

Я получаю сообщение об ошибке, как показано ниже. Есть идеи, что нужно изменить в моем запросе? Спасибо за любые предложения!

XQuery [tblVORRequest.RequestXml.value()]: 'value()' requires a singleton (or empty sequence), found operand of type 'xdt:untypedAtomic *'

1 Ответ

1 голос
/ 07 марта 2020

Скопировано по этой ссылке

XQuery [value ()]: для 'value ()' требуется одиночный (или пустая последовательность) найденный операнд типа 'xdt: untypedAtomi c * '

Хотя в экземпляре XML имеется только один атрибут ProductID, правила ввода stati c требуют, чтобы вы явно указали, что выражение пути возвращает одиночный код. Поэтому дополнительный [1] указывается в конце выражения пути. Для получения дополнительной информации о печати * stati c см. XQuery и Stati c Typing.

Итак, для начала вам нужно всего лишь что-то вроде этого.

DROP TABLE IF EXISTS #temp
CREATE TABLE #temp (test XML)

INSERT INTO #temp
(
    test
)
VALUES
('<User xmlns="">
  <userid>user1</userid>
  <permissions>
    <permission>per1</permission>
    <permission>per2</permission>
    <permission>per3</permission>
  </permissions>
  //Other elements here
</User>'
    )

SELECT UserPermissions.perm.value('permission[1]', 'varchar(50)')
FROM #temp up
cross apply up.test.nodes('/User/permissions') AS UserPermissions (perm)
...