我的 XML 查询 CTE 有什么问题?
What is wrong with my XML query CTE?
基于 this answer,它有一个查询应该 return 来自扩展事件跟踪文件中的事件的 "call stack format" 结果集。
快速查询
SELECT CONVERT (XML, event_data) AS data
FROM sys.fn_xe_file_target_read_file ('C:\Temp\test_trace*.xel', 'C:\Temp\test_trace*.xem', NULL, NULL)
returns 很多结果,显示正在记录事件,最终调用堆栈查询 returns 无结果。该查询基于以下 2 个 CTE:
WITH
CapturedResults AS
( SELECT data.value ( '(/event/@timestamp)[1]', 'DATETIME') AS [TIME],
data.value ( '(/event/data[@name=''cpu'']/value)[1]', 'INT') AS [CPU (ms)],
CONVERT (FLOAT, data.value ('(/event/data[@name=''duration'']/value)[1]', 'BIGINT')) / 1000000 AS [Duration (s)],
data.value ( '(/event/action[@name=''sql_text'']/value)[1]', 'VARCHAR(MAX)') AS [SQL STATEMENT],
CAST(data.value('(/event/action[@name="tsql_stack"]/value)[1]','varchar(MAX)') AS XML) AS [stack_xml]
FROM (
SELECT CONVERT (XML, event_data) AS data
FROM sys.fn_xe_file_target_read_file ('C:\BradySqlTrace\test_trace*.xel', 'C:\BradySqlTrace\test_trace*.xem', NULL, NULL)) entries
),
StackData AS
( SELECT frame_xml.value('(./@level)', 'int') AS [frame_level],
frame_xml.value('(./@handle)', 'varchar(MAX)') AS [sql_handle],
frame_xml.value('(./@offsetStart)', 'int') AS [offset_start],
frame_xml.value('(./@offsetEnd)', 'int') AS [offset_end]
FROM CapturedResults CROSS APPLY stack_xml.nodes('//frame') N (frame_xml)
)
SELECT * FROM StackData
当我从 CapturedResults
select 时,我得到了预期的编号。行数,但是当我查询 StackData
时,我得到的结果为零。
有问题的 XML 节点应该生成 stack_xml
列,如下所示:
<event name="sp_statement_completed" package="sqlserver" timestamp="2017-05-08T12:37:15.132Z">
....
<action name="tsql_stack" package="sqlserver">
<value>
<frames>
<frame level="1" handle="0x03003D0084CC28352EF7C1006DA7000000000000000000000000000000000000000000000000000000000000" line="10" offsetStart="384" offsetEnd="466" />
<frame level="2" handle="0x03003D00DAA5E13A62E99F006DA7000001000000000000000000000000000000000000000000000000000000" line="3" offsetStart="114" offsetEnd="-1" />
<frame level="3" handle="0x01003D005CB2C92D10024E8F0000000000000000000000000000000000000000000000000000000000000000" line="2" offsetStart="4" offsetEnd="-1" />
</frames>
</value>
</action>
</event>
我没有发布整个查询,因为我认为没有结果的第二个 CTE 是问题的开始,我应该首先解决这个问题。整个查询还有 return 个零结果。
您想使用 .query() 而不是 .value() 进行 xml->xml 转换。 .value() 用于 xml->scalar
WITH Events as
(
SELECT CONVERT (XML, event_data) AS data
FROM sys.fn_xe_file_target_read_file ('C:\temp\test*.xel', 'C:\temp\test*.xem', NULL, NULL)
),
CapturedResults AS
( SELECT data.value ( '(/event/@timestamp)[1]', 'DATETIME') AS [TIME],
data.value ( '(/event/data[@name=''cpu'']/value)[1]', 'INT') AS [CPU (ms)],
CONVERT (FLOAT, data.value ('(/event/data[@name=''duration'']/value)[1]', 'BIGINT')) / 1000000 AS [Duration (s)],
data.value ( '(/event/action[@name=''sql_text'']/value)[1]', 'VARCHAR(MAX)') AS [SQL STATEMENT],
data.query('/event/action[@name=''tsql_stack'']/value' ) AS [stack_xml]
FROM Events
),
StackData AS
( SELECT frame_xml.value('(./@level)', 'int') AS [frame_level],
frame_xml.value('(./@handle)', 'varchar(MAX)') AS [sql_handle],
frame_xml.value('(./@offsetStart)', 'int') AS [offset_start],
frame_xml.value('(./@offsetEnd)', 'int') AS [offset_end]
FROM CapturedResults CROSS APPLY stack_xml.nodes('//frame') N (frame_xml)
)
SELECT *
FROM StackData
大卫
基于 this answer,它有一个查询应该 return 来自扩展事件跟踪文件中的事件的 "call stack format" 结果集。
快速查询
SELECT CONVERT (XML, event_data) AS data
FROM sys.fn_xe_file_target_read_file ('C:\Temp\test_trace*.xel', 'C:\Temp\test_trace*.xem', NULL, NULL)
returns 很多结果,显示正在记录事件,最终调用堆栈查询 returns 无结果。该查询基于以下 2 个 CTE:
WITH
CapturedResults AS
( SELECT data.value ( '(/event/@timestamp)[1]', 'DATETIME') AS [TIME],
data.value ( '(/event/data[@name=''cpu'']/value)[1]', 'INT') AS [CPU (ms)],
CONVERT (FLOAT, data.value ('(/event/data[@name=''duration'']/value)[1]', 'BIGINT')) / 1000000 AS [Duration (s)],
data.value ( '(/event/action[@name=''sql_text'']/value)[1]', 'VARCHAR(MAX)') AS [SQL STATEMENT],
CAST(data.value('(/event/action[@name="tsql_stack"]/value)[1]','varchar(MAX)') AS XML) AS [stack_xml]
FROM (
SELECT CONVERT (XML, event_data) AS data
FROM sys.fn_xe_file_target_read_file ('C:\BradySqlTrace\test_trace*.xel', 'C:\BradySqlTrace\test_trace*.xem', NULL, NULL)) entries
),
StackData AS
( SELECT frame_xml.value('(./@level)', 'int') AS [frame_level],
frame_xml.value('(./@handle)', 'varchar(MAX)') AS [sql_handle],
frame_xml.value('(./@offsetStart)', 'int') AS [offset_start],
frame_xml.value('(./@offsetEnd)', 'int') AS [offset_end]
FROM CapturedResults CROSS APPLY stack_xml.nodes('//frame') N (frame_xml)
)
SELECT * FROM StackData
当我从 CapturedResults
select 时,我得到了预期的编号。行数,但是当我查询 StackData
时,我得到的结果为零。
有问题的 XML 节点应该生成 stack_xml
列,如下所示:
<event name="sp_statement_completed" package="sqlserver" timestamp="2017-05-08T12:37:15.132Z">
....
<action name="tsql_stack" package="sqlserver">
<value>
<frames>
<frame level="1" handle="0x03003D0084CC28352EF7C1006DA7000000000000000000000000000000000000000000000000000000000000" line="10" offsetStart="384" offsetEnd="466" />
<frame level="2" handle="0x03003D00DAA5E13A62E99F006DA7000001000000000000000000000000000000000000000000000000000000" line="3" offsetStart="114" offsetEnd="-1" />
<frame level="3" handle="0x01003D005CB2C92D10024E8F0000000000000000000000000000000000000000000000000000000000000000" line="2" offsetStart="4" offsetEnd="-1" />
</frames>
</value>
</action>
</event>
我没有发布整个查询,因为我认为没有结果的第二个 CTE 是问题的开始,我应该首先解决这个问题。整个查询还有 return 个零结果。
您想使用 .query() 而不是 .value() 进行 xml->xml 转换。 .value() 用于 xml->scalar
WITH Events as
(
SELECT CONVERT (XML, event_data) AS data
FROM sys.fn_xe_file_target_read_file ('C:\temp\test*.xel', 'C:\temp\test*.xem', NULL, NULL)
),
CapturedResults AS
( SELECT data.value ( '(/event/@timestamp)[1]', 'DATETIME') AS [TIME],
data.value ( '(/event/data[@name=''cpu'']/value)[1]', 'INT') AS [CPU (ms)],
CONVERT (FLOAT, data.value ('(/event/data[@name=''duration'']/value)[1]', 'BIGINT')) / 1000000 AS [Duration (s)],
data.value ( '(/event/action[@name=''sql_text'']/value)[1]', 'VARCHAR(MAX)') AS [SQL STATEMENT],
data.query('/event/action[@name=''tsql_stack'']/value' ) AS [stack_xml]
FROM Events
),
StackData AS
( SELECT frame_xml.value('(./@level)', 'int') AS [frame_level],
frame_xml.value('(./@handle)', 'varchar(MAX)') AS [sql_handle],
frame_xml.value('(./@offsetStart)', 'int') AS [offset_start],
frame_xml.value('(./@offsetEnd)', 'int') AS [offset_end]
FROM CapturedResults CROSS APPLY stack_xml.nodes('//frame') N (frame_xml)
)
SELECT *
FROM StackData
大卫