SQL-запрос XML для системной таблицы расширенных событий для объекта Session (не файла данных) в поле Предикат_XML
Я запрашиваю системные таблицы для расширенных событий в SQL, чтобы получить некоторые данные о самом расширенном событии, и я хочу получить базу данных, которая устанавливается в расширенных событиях при его создании.
если я выполню этот запрос из системных таблиц здесь:
SELECT SESE.predicate_xml
FROM sys.server_event_sessions SEV
LEFT OUTER JOIN sys.server_event_session_fields SESF ON SEV.event_session_id = SESF.event_session_id
LEFT OUTER JOIN sys.server_event_session_events SESE ON SEV.event_session_id = SESE.event_session_id
Я могу получить строку XML для предиката_XML, которая дает мне XML, похожий на тот:
<and>
<and>
<or>
<leaf>
<comparator name="equal_uint64" package="package0" />
<event name="sp_statement_starting" package="sqlserver" field="object_type" />
<value>8272</value>
</leaf>
<leaf>
<comparator name="equal_uint64" package="package0" />
<event name="sp_statement_starting" package="sqlserver" field="object_type" />
<value>20038</value>
</leaf>
</or>
<leaf>
<comparator name="equal_i_sql_unicode_string" package="sqlserver" />
<global name="database_name" package="sqlserver" />
<value>DatabasenameHere</value>
</leaf>
</and>
<leaf>
<comparator name="equal_boolean" package="package0" />
<global name="is_system" package="sqlserver" />
<value>false</value>
</leaf>
</and>
Есть XML для database_name, и я хочу получить значение для этого.
Это очень простое расширенное событие, поэтому существует очень маленький XML, но он может стать большим, и может иметь несколько баз данных, и / или в XML может быть более сложным, поэтому я не могу сделать простой запрос, чтобы просто найти топ / первый. Для этого конкретного XML этот запрос работает, но он не будет работать для других / всех:
DECLARE @XML AS XML = '<and><and><or><leaf><comparator name="equal_uint64" package="package0"></comparator><event name="sp_statement_starting" package="sqlserver" field="object_type"></event><value>8272</value></leaf><leaf><comparator name="equal_uint64" package="package0"></comparator><event name="sp_statement_starting" package="sqlserver" field="object_type"></event><value>20038</value></leaf></or><leaf><comparator name="equal_i_sql_unicode_string" package="sqlserver"></comparator><global name="database_name" package="sqlserver"></global><value><![CDATA[SubmissionEngine]]></value></leaf></and><leaf><comparator name="equal_boolean" package="package0"></comparator><global name="is_system" package="sqlserver"></global><value>false</value></leaf></and>'
SELECT @XML
SELECT T.c.value('.', 'varchar(100)') AS result
--,T.c.value('.') AS ObjectType
FROM @XML.nodes('/and/and/leaf/value') T(c)
GO
Посоветуйте, пожалуйста, о том, что / как я могу запросить этот тип XML, чтобы получить имя_базы_данных из XML (и, если их несколько, также получить их)
1 ответ
Опять же, я не уверен, правильно ли я понял, но вы можете попробовать более общий поиск:
Внимание: я добавил еще один узел с именем базы данных, чтобы продемонстрировать, что поиск не зависит ни от позиции, ни от названия.
DECLARE @xml XML=
N'<and>
<and>
<or>
<leaf>
<comparator name="equal_uint64" package="package0" />
<event name="sp_statement_starting" package="sqlserver" field="object_type" />
<value>8272</value>
</leaf>
<leaf>
<comparator name="equal_uint64" package="package0" />
<event name="sp_statement_starting" package="sqlserver" field="object_type" />
<value>20038</value>
</leaf>
</or>
<leaf>
<comparator name="equal_i_sql_unicode_string" package="sqlserver" />
<global name="database_name" package="sqlserver" />
<value>DatabasenameHere</value>
</leaf>
</and>
<leaf>
<comparator name="equal_boolean" package="package0" />
<global name="is_system" package="sqlserver" />
<value>false</value>
</leaf>
<test>
<anyelement name="database_name"/>
<value>OneMoreDB</value>
</test>
</and>';
- запрос
SELECT vals.value('text()[1]','nvarchar(max)')
FROM @xml.nodes('//*[*[@name="database_name"]]/value') A(vals);
Вы можете прочитать это как:
- Поиск в любом месте (глубокий поиск с
//
) - найти любой элемент
- где есть какой-либо элемент на следующем уровне с атрибутом
name
со значением "database_name"
- где есть какой-либо элемент на следующем уровне с атрибутом
- и взять
<value>
под элементом