SQL 在 predicate_XML 字段中查询 XML 扩展事件系统 table 会话对象(不是数据文件)
SQL Query XML for Extended Events system table for Session object (not data file) in predicate_XML field
我在 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
我可以为 predicate_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>
database_name 有一个 XML,我想获取它的值。
这是一个非常简单的扩展事件,所以有一个非常小的 XML,但它可以变大,并且可以有多个数据库以及 XML 中的 and/or更复杂,所以我不能做一个简单的查询来找到 top/first 一个。对于这个特定的 XML 这个查询有效,但它不会在 others/all:
上工作
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
请指教 what/how 我可以查询这种类型的 XML 以从 XML 中获取 database_name(如果有多个,也获取它们)
同样,我不确定是否正确,但您可以尝试更通用的搜索:
注意:我添加了另一个带有数据库名称的节点来演示,搜索既不依赖于位置也不依赖于命名。
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>
我在 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
我可以为 predicate_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>
database_name 有一个 XML,我想获取它的值。
这是一个非常简单的扩展事件,所以有一个非常小的 XML,但它可以变大,并且可以有多个数据库以及 XML 中的 and/or更复杂,所以我不能做一个简单的查询来找到 top/first 一个。对于这个特定的 XML 这个查询有效,但它不会在 others/all:
上工作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
请指教 what/how 我可以查询这种类型的 XML 以从 XML 中获取 database_name(如果有多个,也获取它们)
同样,我不确定是否正确,但您可以尝试更通用的搜索:
注意:我添加了另一个带有数据库名称的节点来演示,搜索既不依赖于位置也不依赖于命名。
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>