过度扩张
在阻塞进程报告和死锁 XML 的 SQL Server 扩展事件中,可以获取多个 SQL 句柄值以识别引发事件中涉及的查询。
由于可能涉及到一个或多个 SQL 句柄,因此可靠地查询 XML 以检索它们可能很困难,并且还会使更直接的 XQuery 不正确,因为它只检索第一个存储的值。
sqlhandle = bd.value('(process/executionStack/frame/@sqlhandle)[1]', 'varchar(130)'),
用于说明的示例 XML 片段如下所示:
<executionStack>
<frame line="1" stmtend="108" sqlhandle="0x020000008d18260040e407ba48fc247b0cb6121c21c2cf2b0000000000000000000000000000000000000000" />
<frame line="1" stmtend="108" sqlhandle="0x02000000dd847b18dcaa4a09a89f56595186fcf91da8a7f70000000000000000000000000000000000000000" />
</executionStack>
此 SQL Fiddle提供了更完整的示例。
我已经做到了:
SELECT
sql_handle =
@x.query('for $s in //executionStack/frame return $s');
但这并没有得到我所追求的。扩展该查询以使用该@sqlhandle
属性会引发错误:
SELECT
sql_handle =
@x.query('for $s in //executionStack/frame/@sqlhandle return $s');
消息 2396,级别 16,状态 1,第 60 行 XQuery [query()]:属性可能不会出现在元素之外
如何像这样查询 XML 以将所有列出的 SQL 句柄作为逗号分隔列表返回?
尝试这样的事情:
要克服错误消息“属性可能不会出现在元素之外”,您可以使用该
string
函数。上面返回一个空格分隔的列表,但由于 SQL 句柄本身不能包含空格,在这种情况下,您可以只使用 a
REPLACE
来获得所需的逗号分隔的最终结果。或者做
或者,您可以使用
concat
或Paul White 在评论中提供的另一种替代方案Erik 最终使用的代码
sp_HumanEvents
是:本质上,您的问题是您将实际属性作为顶级节点返回,这是您无法做到的。相反,您需要将其原子化为字符串。您可以明确地执行此操作,但无论如何您都需要
concat
,它会为您执行此操作。因此您可以使用以下 XQuery 语法
for $x in your/Xquery/path return concat($x/@attributeName, ",")
此外,您应该始终尝试使用
/
子轴,而不是//
后代轴,因为它更快。db<>小提琴