xQuery - несколько узлов - PullRequest
       8

xQuery - несколько узлов

0 голосов
/ 06 ноября 2018

У меня следующий запрос:

SELECT     
CAST(spi.dbo.UserInfo.XmlContent AS xml).value('(/UserInfo[1]/@SystemId)','VARCHAR(32)') as SystemId,
CAST(spi.dbo.UserInfo.XmlContent AS xml).value('(/UserInfo[1]/@LoginId)','VARCHAR(32)') as LoginId,
--CAST(spi.dbo.UserInfo.XmlContent AS xml).value('(/UserInfo[1]/ChangeInfo/@UserId)[3]','VARCHAR(32)')AS SystemID
CAST(spi.dbo.UserInfo.XmlContent AS xml).value('count(/UserInfo/ChangeInfo)', 'INT') AS 'Count'
FROM UserInfo
WHERE CAST(spi.dbo.UserInfo.XmlContent AS xml).value('(/UserInfo[1]/ChangeInfo)[1]','VARCHAR(32)') = 'John'

Проблема, с которой я сталкиваюсь, заключается в том, что узел ChangeInfo может быть кратным в некоторых записях XML.

Как я могу искать все узлы, вместо того, чтобы указывать количество узлов, например, ChangeInfo[1]?

1 Ответ

0 голосов
/ 07 ноября 2018

Зачем вам нужно навести колонку XmlContent? Это должен быть столбец собственного типа XML ... Это приведение очень дорого, а хранение XML в столбце, отличном от XML, очень ошибочно ...

Не показывая ваш XML, это летающий с завязанными глазами , но мой волшебный хрустальный шар сказал мне, что вы можете искать что-то вроде этого:

SELECT     
    A.CastedToXml.value('(/UserInfo/@SystemId)[1]','VARCHAR(32)') as SystemId,
    A.CastedToXml.value('(/UserInfo/@LoginId)[1]','VARCHAR(32)') as LoginId,
    B.ci.value('(/UserInfo/ChangeInfo/@UserId)[1]','VARCHAR(32)') AS ChangeInfo_UserID,
    A.CastedToXml.value('count(/UserInfo/ChangeInfo)', 'INT') AS ChangeInfo_Count
FROM spi.dbo.UserInfo ui
OUTER APPLY(SELECT CAST(ui.XmlContent AS xml)) A(CastedToXml)
OUTER APPLY A.CastedToXml.nodes('/UserInfo/ChangeInfo') B(ci)
WHERE CastedToXml.exist('/UserInfo/ChangeInfo[text()="John"]')=1;

Я использую APPLY, чтобы добавить xml-castted столбец к набору результатов. Второй APPLY вернет все вложенные элементы <ChangeInfo> как производную таблицу.

В предложении WHERE используется метод XML .exist(). Это проверит любое вхождение указанного Xpath в любом месте XML. При необходимости вы можете динамически вводить литерал «Джон» с помощью sql:variable() или sql:column извне.

Один совет: попробуйте узнать об псевдонимах таблиц и о том, как избежать повторения кода.

...