Зачем вам нужно навести колонку 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
извне.
Один совет: попробуйте узнать об псевдонимах таблиц и о том, как избежать повторения кода.