-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path02_ParseTsqlStack.sql
56 lines (55 loc) · 1.29 KB
/
02_ParseTsqlStack.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
DECLARE @stackOrFrame xml = '' /* input the tsql_stack xml in format: <frames>…</frames> */
/*
The xml format is for a clickable text.
If your text contains special XML characters, you will need to tweak this code
*/
;WITH
xmlShred AS
(
SELECT
COALESCE
(
CONVERT(varbinary(64), f.n.value('.[1]/@handle', 'varchar(max)'), 1),
CONVERT(varbinary(64), f.n.value('.[1]/@sqlhandle', 'varchar(max)'), 1)
) AS handle,
COALESCE
(
f.n.value('.[1]/@offsetStart', 'int'),
f.n.value('.[1]/@stmtstart', 'int')
) AS offsetStart,
COALESCE
(
f.n.value('.[1]/@offsetEnd', 'int'),
f.n.value('.[1]/@stmtend', 'int')
) AS offsetEnd,
f.n.value('.[1]/@line', 'int') AS line,
f.n.value('.[1]/@level', 'tinyint') AS stackLevel
FROM @stackOrFrame.nodes('//frame') AS f(n)
)
SELECT
xs.stackLevel,
ca.outerText,
ca2.statementText
FROM
xmlShred AS xs
CROSS APPLY sys.dm_exec_sql_text(xs.handle) AS dest
CROSS APPLY (SELECT dest.text FOR XML PATH(''), TYPE) AS ca(outerText)
CROSS APPLY
(
SELECT
SUBSTRING
( dest.text,
xs.offsetStart / 2,
(
CASE
WHEN xs.offsetEnd = -1
THEN DATALENGTH(dest.text)
ELSE xs.offsetEnd
END
- xs.offsetStart / 2
) / 2
)
FOR XML PATH(''), TYPE
) AS ca2(statementText)
ORDER BY xs.stackLevel
OPTION (RECOMPILE);