经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 数据库/运维 » MS SQL Server » 查看文章
SQL Server 查看当前会话状态【sp_WhoIsActive 转载】
来源:cnblogs  作者:东山絮柳仔  时间:2021/6/29 3:56:16  对本文有异议

 一.常见简便的方式

通常,DBA使用sp_who和sp_who2系统存储过程或活动监视器来查看SQL实例中的当前会话、用户和进程。 我们还可以从这些过程中确定阻塞会话和活动会话。

1.1. Sp_who 如下:

1.2 Sp_who2 如下:

1.3 通过SQL Server活动监视器(SQL Server Activity Monitor)

进程窗格如下

二. sp_WhoIsActive

这些过程没有提供太多有用的信息,例如等待信息,执行计划,当前运行的语句,持续时间。 现在,让我介绍另一个有用的存储过程sp_WhoIsActive,以获取SQL Server用户进程的即时视图。 它由Microsoft MVP Adam Machanic开发 。 我们可以从SQL Server 2005开始使用此存储过程。 您可以参考whoisactive的官方文档。 它从各种DMV收集数据,并以表格格式显示信息。

这是一个自定义存储过程。 我们可以从GitHub下载最新版本。 当前版本是11.35。 打开URL并下载其ZIP版本。

 

 

 其完整代码如下:

  1. SET QUOTED_IDENTIFIER ON;
  2. SET ANSI_PADDING ON;
  3. SET CONCAT_NULL_YIELDS_NULL ON;
  4. SET ANSI_WARNINGS ON;
  5. SET NUMERIC_ROUNDABORT OFF;
  6. SET ARITHABORT ON;
  7. GO
  8.  
  9. IF NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_NAME = 'sp_WhoIsActive')
  10. EXEC ('CREATE PROC dbo.sp_WhoIsActive AS SELECT ''stub version, to be replaced''')
  11. GO
  12.  
  13. /*********************************************************************************************
  14. Who Is Active? v11.35 (2020-10-04)
  15. (C) 2007-2020, Adam Machanic
  16. Feedback: mailto:adam@dataeducation.com
  17. Updates: http://whoisactive.com
  18. Blog: http://dataeducation.com
  19. License:
  20. https://github.com/amachanic/sp_whoisactive/blob/master/LICENSE
  21. *********************************************************************************************/
  22. ALTER PROC dbo.sp_WhoIsActive
  23. (
  24. --~
  25. --Filters--Both inclusive and exclusive
  26. --Set either filter to '' to disable
  27. --Valid filter types are: session, program, database, login, and host
  28. --Session is a session ID, and either 0 or '' can be used to indicate "all" sessions
  29. --All other filter types support % or _ as wildcards
  30. @filter sysname = '',
  31. @filter_type VARCHAR(10) = 'session',
  32. @not_filter sysname = '',
  33. @not_filter_type VARCHAR(10) = 'session',
  34. --Retrieve data about the calling session?
  35. @show_own_spid BIT = 0,
  36. --Retrieve data about system sessions?
  37. @show_system_spids BIT = 0,
  38. --Controls how sleeping SPIDs are handled, based on the idea of levels of interest
  39. --0 does not pull any sleeping SPIDs
  40. --1 pulls only those sleeping SPIDs that also have an open transaction
  41. --2 pulls all sleeping SPIDs
  42. @show_sleeping_spids TINYINT = 1,
  43. --If 1, gets the full stored procedure or running batch, when available
  44. --If 0, gets only the actual statement that is currently running in the batch or procedure
  45. @get_full_inner_text BIT = 0,
  46. --Get associated query plans for running tasks, if available
  47. --If @get_plans = 1, gets the plan based on the request's statement offset
  48. --If @get_plans = 2, gets the entire plan based on the request's plan_handle
  49. @get_plans TINYINT = 0,
  50. --Get the associated outer ad hoc query or stored procedure call, if available
  51. @get_outer_command BIT = 0,
  52. --Enables pulling transaction log write info and transaction duration
  53. @get_transaction_info BIT = 0,
  54. --Get information on active tasks, based on three interest levels
  55. --Level 0 does not pull any task-related information
  56. --Level 1 is a lightweight mode that pulls the top non-CXPACKET wait, giving preference to blockers
  57. --Level 2 pulls all available task-based metrics, including:
  58. --number of active tasks, current wait stats, physical I/O, context switches, and blocker information
  59. @get_task_info TINYINT = 1,
  60. --Gets associated locks for each request, aggregated in an XML format
  61. @get_locks BIT = 0,
  62. --Get average time for past runs of an active query
  63. --(based on the combination of plan handle, sql handle, and offset)
  64. @get_avg_time BIT = 0,
  65. --Get additional non-performance-related information about the session or request
  66. --text_size, language, date_format, date_first, quoted_identifier, arithabort, ansi_null_dflt_on,
  67. --ansi_defaults, ansi_warnings, ansi_padding, ansi_nulls, concat_null_yields_null,
  68. --transaction_isolation_level, lock_timeout, deadlock_priority, row_count, command_type
  69. --
  70. --If a SQL Agent job is running, an subnode called agent_info will be populated with some or all of
  71. --the following: job_id, job_name, step_id, step_name, msdb_query_error (in the event of an error)
  72. --
  73. --If @get_task_info is set to 2 and a lock wait is detected, a subnode called block_info will be
  74. --populated with some or all of the following: lock_type, database_name, object_id, file_id, hobt_id,
  75. --applock_hash, metadata_resource, metadata_class_id, object_name, schema_name
  76. @get_additional_info BIT = 0,
  77. --Walk the blocking chain and count the number of
  78. --total SPIDs blocked all the way down by a given session
  79. --Also enables task_info Level 1, if @get_task_info is set to 0
  80. @find_block_leaders BIT = 0,
  81. --Pull deltas on various metrics
  82. --Interval in seconds to wait before doing the second data pull
  83. @delta_interval TINYINT = 0,
  84. --List of desired output columns, in desired order
  85. --Note that the final output will be the intersection of all enabled features and all
  86. --columns in the list. Therefore, only columns associated with enabled features will
  87. --actually appear in the output. Likewise, removing columns from this list may effectively
  88. --disable features, even if they are turned on
  89. --
  90. --Each element in this list must be one of the valid output column names. Names must be
  91. --delimited by square brackets. White space, formatting, and additional characters are
  92. --allowed, as long as the list contains exact matches of delimited valid column names.
  93. @output_column_list VARCHAR(8000) = '[dd%][session_id][sql_text][sql_command][login_name][wait_info][tasks][tran_log%][cpu%][temp%][block%][reads%][writes%][context%][physical%][query_plan][locks][%]',
  94. --Column(s) by which to sort output, optionally with sort directions.
  95. --Valid column choices:
  96. --session_id, physical_io, reads, physical_reads, writes, tempdb_allocations,
  97. --tempdb_current, CPU, context_switches, used_memory, physical_io_delta, reads_delta,
  98. --physical_reads_delta, writes_delta, tempdb_allocations_delta, tempdb_current_delta,
  99. --CPU_delta, context_switches_delta, used_memory_delta, tasks, tran_start_time,
  100. --open_tran_count, blocking_session_id, blocked_session_count, percent_complete,
  101. --host_name, login_name, database_name, start_time, login_time, program_name
  102. --
  103. --Note that column names in the list must be bracket-delimited. Commas and/or white
  104. --space are not required.
  105. @sort_order VARCHAR(500) = '[start_time] ASC',
  106. --Formats some of the output columns in a more "human readable" form
  107. --0 disables outfput format
  108. --1 formats the output for variable-width fonts
  109. --2 formats the output for fixed-width fonts
  110. @format_output TINYINT = 1,
  111. --If set to a non-blank value, the script will attempt to insert into the specified
  112. --destination table. Please note that the script will not verify that the table exists,
  113. --or that it has the correct schema, before doing the insert.
  114. --Table can be specified in one, two, or three-part format
  115. @destination_table VARCHAR(4000) = '',
  116. --If set to 1, no data collection will happen and no result set will be returned; instead,
  117. --a CREATE TABLE statement will be returned via the @schema parameter, which will match
  118. --the schema of the result set that would be returned by using the same collection of the
  119. --rest of the parameters. The CREATE TABLE statement will have a placeholder token of
  120. --<table_name> in place of an actual table name.
  121. @return_schema BIT = 0,
  122. @schema VARCHAR(MAX) = NULL OUTPUT,
  123. --Help! What do I do?
  124. @help BIT = 0
  125. --~
  126. )
  127. /*
  128. OUTPUT COLUMNS
  129. --------------
  130. Formatted/Non: [session_id] [smallint] NOT NULL
  131. Session ID (a.k.a. SPID)
  132. Formatted: [dd hh:mm:ss.mss] [varchar](15) NULL
  133. Non-Formatted: <not returned>
  134. For an active request, time the query has been running
  135. For a sleeping session, time since the last batch completed
  136. Formatted: [dd hh:mm:ss.mss (avg)] [varchar](15) NULL
  137. Non-Formatted: [avg_elapsed_time] [int] NULL
  138. (Requires @get_avg_time option)
  139. How much time has the active portion of the query taken in the past, on average?
  140. Formatted: [physical_io] [varchar](30) NULL
  141. Non-Formatted: [physical_io] [bigint] NULL
  142. Shows the number of physical I/Os, for active requests
  143. Formatted: [reads] [varchar](30) NULL
  144. Non-Formatted: [reads] [bigint] NULL
  145. For an active request, number of reads done for the current query
  146. For a sleeping session, total number of reads done over the lifetime of the session
  147. Formatted: [physical_reads] [varchar](30) NULL
  148. Non-Formatted: [physical_reads] [bigint] NULL
  149. For an active request, number of physical reads done for the current query
  150. For a sleeping session, total number of physical reads done over the lifetime of the session
  151. Formatted: [writes] [varchar](30) NULL
  152. Non-Formatted: [writes] [bigint] NULL
  153. For an active request, number of writes done for the current query
  154. For a sleeping session, total number of writes done over the lifetime of the session
  155. Formatted: [tempdb_allocations] [varchar](30) NULL
  156. Non-Formatted: [tempdb_allocations] [bigint] NULL
  157. For an active request, number of TempDB writes done for the current query
  158. For a sleeping session, total number of TempDB writes done over the lifetime of the session
  159. Formatted: [tempdb_current] [varchar](30) NULL
  160. Non-Formatted: [tempdb_current] [bigint] NULL
  161. For an active request, number of TempDB pages currently allocated for the query
  162. For a sleeping session, number of TempDB pages currently allocated for the session
  163. Formatted: [CPU] [varchar](30) NULL
  164. Non-Formatted: [CPU] [int] NULL
  165. For an active request, total CPU time consumed by the current query
  166. For a sleeping session, total CPU time consumed over the lifetime of the session
  167. Formatted: [context_switches] [varchar](30) NULL
  168. Non-Formatted: [context_switches] [bigint] NULL
  169. Shows the number of context switches, for active requests
  170. Formatted: [used_memory] [varchar](30) NOT NULL
  171. Non-Formatted: [used_memory] [bigint] NOT NULL
  172. For an active request, total memory consumption for the current query
  173. For a sleeping session, total current memory consumption
  174. Formatted: [physical_io_delta] [varchar](30) NULL
  175. Non-Formatted: [physical_io_delta] [bigint] NULL
  176. (Requires @delta_interval option)
  177. Difference between the number of physical I/Os reported on the first and second collections.
  178. If the request started after the first collection, the value will be NULL
  179. Formatted: [reads_delta] [varchar](30) NULL
  180. Non-Formatted: [reads_delta] [bigint] NULL
  181. (Requires @delta_interval option)
  182. Difference between the number of reads reported on the first and second collections.
  183. If the request started after the first collection, the value will be NULL
  184. Formatted: [physical_reads_delta] [varchar](30) NULL
  185. Non-Formatted: [physical_reads_delta] [bigint] NULL
  186. (Requires @delta_interval option)
  187. Difference between the number of physical reads reported on the first and second collections.
  188. If the request started after the first collection, the value will be NULL
  189. Formatted: [writes_delta] [varchar](30) NULL
  190. Non-Formatted: [writes_delta] [bigint] NULL
  191. (Requires @delta_interval option)
  192. Difference between the number of writes reported on the first and second collections.
  193. If the request started after the first collection, the value will be NULL
  194. Formatted: [tempdb_allocations_delta] [varchar](30) NULL
  195. Non-Formatted: [tempdb_allocations_delta] [bigint] NULL
  196. (Requires @delta_interval option)
  197. Difference between the number of TempDB writes reported on the first and second collections.
  198. If the request started after the first collection, the value will be NULL
  199. Formatted: [tempdb_current_delta] [varchar](30) NULL
  200. Non-Formatted: [tempdb_current_delta] [bigint] NULL
  201. (Requires @delta_interval option)
  202. Difference between the number of allocated TempDB pages reported on the first and second
  203. collections. If the request started after the first collection, the value will be NULL
  204. Formatted: [CPU_delta] [varchar](30) NULL
  205. Non-Formatted: [CPU_delta] [int] NULL
  206. (Requires @delta_interval option)
  207. Difference between the CPU time reported on the first and second collections.
  208. If the request started after the first collection, the value will be NULL
  209. Formatted: [context_switches_delta] [varchar](30) NULL
  210. Non-Formatted: [context_switches_delta] [bigint] NULL
  211. (Requires @delta_interval option)
  212. Difference between the context switches count reported on the first and second collections
  213. If the request started after the first collection, the value will be NULL
  214. Formatted: [used_memory_delta] [varchar](30) NULL
  215. Non-Formatted: [used_memory_delta] [bigint] NULL
  216. Difference between the memory usage reported on the first and second collections
  217. If the request started after the first collection, the value will be NULL
  218. Formatted: [tasks] [varchar](30) NULL
  219. Non-Formatted: [tasks] [smallint] NULL
  220. Number of worker tasks currently allocated, for active requests
  221. Formatted/Non: [status] [varchar](30) NOT NULL
  222. Activity status for the session (running, sleeping, etc)
  223. Formatted/Non: [wait_info] [nvarchar](4000) NULL
  224. Aggregates wait information, in the following format:
  225. (Ax: Bms/Cms/Dms)E
  226. A is the number of waiting tasks currently waiting on resource type E. B/C/D are wait
  227. times, in milliseconds. If only one thread is waiting, its wait time will be shown as B.
  228. If two tasks are waiting, each of their wait times will be shown (B/C). If three or more
  229. tasks are waiting, the minimum, average, and maximum wait times will be shown (B/C/D).
  230. If wait type E is a page latch wait and the page is of a "special" type (e.g. PFS, GAM, SGAM),
  231. the page type will be identified.
  232. If wait type E is CXPACKET, the nodeId from the query plan will be identified
  233. Formatted/Non: [locks] [xml] NULL
  234. (Requires @get_locks option)
  235. Aggregates lock information, in XML format.
  236. The lock XML includes the lock mode, locked object, and aggregates the number of requests.
  237. Attempts are made to identify locked objects by name
  238. Formatted/Non: [tran_start_time] [datetime] NULL
  239. (Requires @get_transaction_info option)
  240. Date and time that the first transaction opened by a session caused a transaction log
  241. write to occur.
  242. Formatted/Non: [tran_log_writes] [nvarchar](4000) NULL
  243. (Requires @get_transaction_info option)
  244. Aggregates transaction log write information, in the following format:
  245. A:wB (C kB)
  246. A is a database that has been touched by an active transaction
  247. B is the number of log writes that have been made in the database as a result of the transaction
  248. C is the number of log kilobytes consumed by the log records
  249. Formatted: [open_tran_count] [varchar](30) NULL
  250. Non-Formatted: [open_tran_count] [smallint] NULL
  251. Shows the number of open transactions the session has open
  252. Formatted: [sql_command] [xml] NULL
  253. Non-Formatted: [sql_command] [nvarchar](max) NULL
  254. (Requires @get_outer_command option)
  255. Shows the "outer" SQL command, i.e. the text of the batch or RPC sent to the server,
  256. if available
  257. Formatted: [sql_text] [xml] NULL
  258. Non-Formatted: [sql_text] [nvarchar](max) NULL
  259. Shows the SQL text for active requests or the last statement executed
  260. for sleeping sessions, if available in either case.
  261. If @get_full_inner_text option is set, shows the full text of the batch.
  262. Otherwise, shows only the active statement within the batch.
  263. If the query text is locked, a special timeout message will be sent, in the following format:
  264. <timeout_exceeded />
  265. If an error occurs, an error message will be sent, in the following format:
  266. <error message="message" />
  267. Formatted/Non: [query_plan] [xml] NULL
  268. (Requires @get_plans option)
  269. Shows the query plan for the request, if available.
  270. If the plan is locked, a special timeout message will be sent, in the following format:
  271. <timeout_exceeded />
  272. If an error occurs, an error message will be sent, in the following format:
  273. <error message="message" />
  274. Formatted/Non: [blocking_session_id] [smallint] NULL
  275. When applicable, shows the blocking SPID
  276. Formatted: [blocked_session_count] [varchar](30) NULL
  277. Non-Formatted: [blocked_session_count] [smallint] NULL
  278. (Requires @find_block_leaders option)
  279. The total number of SPIDs blocked by this session,
  280. all the way down the blocking chain.
  281. Formatted: [percent_complete] [varchar](30) NULL
  282. Non-Formatted: [percent_complete] [real] NULL
  283. When applicable, shows the percent complete (e.g. for backups, restores, and some rollbacks)
  284. Formatted/Non: [host_name] [sysname] NOT NULL
  285. Shows the host name for the connection
  286. Formatted/Non: [login_name] [sysname] NOT NULL
  287. Shows the login name for the connection
  288. Formatted/Non: [database_name] [sysname] NULL
  289. Shows the connected database
  290. Formatted/Non: [program_name] [sysname] NULL
  291. Shows the reported program/application name
  292. Formatted/Non: [additional_info] [xml] NULL
  293. (Requires @get_additional_info option)
  294. Returns additional non-performance-related session/request information
  295. If the script finds a SQL Agent job running, the name of the job and job step will be reported
  296. If @get_task_info = 2 and the script finds a lock wait, the locked object will be reported
  297. Formatted/Non: [start_time] [datetime] NOT NULL
  298. For active requests, shows the time the request started
  299. For sleeping sessions, shows the time the last batch completed
  300. Formatted/Non: [login_time] [datetime] NOT NULL
  301. Shows the time that the session connected
  302. Formatted/Non: [request_id] [int] NULL
  303. For active requests, shows the request_id
  304. Should be 0 unless MARS is being used
  305. Formatted/Non: [collection_time] [datetime] NOT NULL
  306. Time that this script's final SELECT ran
  307. */
  308. AS
  309. BEGIN;
  310. SET NOCOUNT ON;
  311. SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
  312. SET QUOTED_IDENTIFIER ON;
  313. SET ANSI_PADDING ON;
  314. SET CONCAT_NULL_YIELDS_NULL ON;
  315. SET ANSI_WARNINGS ON;
  316. SET NUMERIC_ROUNDABORT OFF;
  317. SET ARITHABORT ON;
  318. IF
  319. @filter IS NULL
  320. OR @filter_type IS NULL
  321. OR @not_filter IS NULL
  322. OR @not_filter_type IS NULL
  323. OR @show_own_spid IS NULL
  324. OR @show_system_spids IS NULL
  325. OR @show_sleeping_spids IS NULL
  326. OR @get_full_inner_text IS NULL
  327. OR @get_plans IS NULL
  328. OR @get_outer_command IS NULL
  329. OR @get_transaction_info IS NULL
  330. OR @get_task_info IS NULL
  331. OR @get_locks IS NULL
  332. OR @get_avg_time IS NULL
  333. OR @get_additional_info IS NULL
  334. OR @find_block_leaders IS NULL
  335. OR @delta_interval IS NULL
  336. OR @format_output IS NULL
  337. OR @output_column_list IS NULL
  338. OR @sort_order IS NULL
  339. OR @return_schema IS NULL
  340. OR @destination_table IS NULL
  341. OR @help IS NULL
  342. BEGIN;
  343. RAISERROR('Input parameters cannot be NULL', 16, 1);
  344. RETURN;
  345. END;
  346. IF @filter_type NOT IN ('session', 'program', 'database', 'login', 'host')
  347. BEGIN;
  348. RAISERROR('Valid filter types are: session, program, database, login, host', 16, 1);
  349. RETURN;
  350. END;
  351. IF @filter_type = 'session' AND @filter LIKE '%[^0123456789]%'
  352. BEGIN;
  353. RAISERROR('Session filters must be valid integers', 16, 1);
  354. RETURN;
  355. END;
  356. IF @not_filter_type NOT IN ('session', 'program', 'database', 'login', 'host')
  357. BEGIN;
  358. RAISERROR('Valid filter types are: session, program, database, login, host', 16, 1);
  359. RETURN;
  360. END;
  361. IF @not_filter_type = 'session' AND @not_filter LIKE '%[^0123456789]%'
  362. BEGIN;
  363. RAISERROR('Session filters must be valid integers', 16, 1);
  364. RETURN;
  365. END;
  366. IF @show_sleeping_spids NOT IN (0, 1, 2)
  367. BEGIN;
  368. RAISERROR('Valid values for @show_sleeping_spids are: 0, 1, or 2', 16, 1);
  369. RETURN;
  370. END;
  371. IF @get_plans NOT IN (0, 1, 2)
  372. BEGIN;
  373. RAISERROR('Valid values for @get_plans are: 0, 1, or 2', 16, 1);
  374. RETURN;
  375. END;
  376. IF @get_task_info NOT IN (0, 1, 2)
  377. BEGIN;
  378. RAISERROR('Valid values for @get_task_info are: 0, 1, or 2', 16, 1);
  379. RETURN;
  380. END;
  381. IF @format_output NOT IN (0, 1, 2)
  382. BEGIN;
  383. RAISERROR('Valid values for @format_output are: 0, 1, or 2', 16, 1);
  384. RETURN;
  385. END;
  386. IF @help = 1
  387. BEGIN;
  388. DECLARE
  389. @header VARCHAR(MAX),
  390. @params VARCHAR(MAX),
  391. @outputs VARCHAR(MAX);
  392. SELECT
  393. @header =
  394. REPLACE
  395. (
  396. REPLACE
  397. (
  398. CONVERT
  399. (
  400. VARCHAR(MAX),
  401. SUBSTRING
  402. (
  403. t.text,
  404. CHARINDEX('/' + REPLICATE('*', 93), t.text) + 94,
  405. CHARINDEX(REPLICATE('*', 93) + '/', t.text) - (CHARINDEX('/' + REPLICATE('*', 93), t.text) + 94)
  406. )
  407. ),
  408. CHAR(13)+CHAR(10),
  409. CHAR(13)
  410. ),
  411. ' ',
  412. ''
  413. ),
  414. @params =
  415. CHAR(13) +
  416. REPLACE
  417. (
  418. REPLACE
  419. (
  420. CONVERT
  421. (
  422. VARCHAR(MAX),
  423. SUBSTRING
  424. (
  425. t.text,
  426. CHARINDEX('--~', t.text) + 5,
  427. CHARINDEX('--~', t.text, CHARINDEX('--~', t.text) + 5) - (CHARINDEX('--~', t.text) + 5)
  428. )
  429. ),
  430. CHAR(13)+CHAR(10),
  431. CHAR(13)
  432. ),
  433. ' ',
  434. ''
  435. ),
  436. @outputs =
  437. CHAR(13) +
  438. REPLACE
  439. (
  440. REPLACE
  441. (
  442. REPLACE
  443. (
  444. CONVERT
  445. (
  446. VARCHAR(MAX),
  447. SUBSTRING
  448. (
  449. t.text,
  450. CHARINDEX('OUTPUT COLUMNS'+CHAR(13)+CHAR(10)+'--------------', t.text) + 32,
  451. CHARINDEX('*/', t.text, CHARINDEX('OUTPUT COLUMNS'+CHAR(13)+CHAR(10)+'--------------', t.text) + 32) - (CHARINDEX('OUTPUT COLUMNS'+CHAR(13)+CHAR(10)+'--------------', t.text) + 32)
  452. )
  453. ),
  454. CHAR(9),
  455. CHAR(255)
  456. ),
  457. CHAR(13)+CHAR(10),
  458. CHAR(13)
  459. ),
  460. ' ',
  461. ''
  462. ) +
  463. CHAR(13)
  464. FROM sys.dm_exec_requests AS r
  465. CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) AS t
  466. WHERE
  467. r.session_id = @@SPID;
  468. WITH
  469. a0 AS
  470. (SELECT 1 AS n UNION ALL SELECT 1),
  471. a1 AS
  472. (SELECT 1 AS n FROM a0 AS a CROSS JOIN a0 AS b),
  473. a2 AS
  474. (SELECT 1 AS n FROM a1 AS a CROSS JOIN a1 AS b),
  475. a3 AS
  476. (SELECT 1 AS n FROM a2 AS a CROSS JOIN a2 AS b),
  477. a4 AS
  478. (SELECT 1 AS n FROM a3 AS a CROSS JOIN a3 AS b),
  479. numbers AS
  480. (
  481. SELECT TOP(LEN(@header) - 1)
  482. ROW_NUMBER() OVER
  483. (
  484. ORDER BY (SELECT NULL)
  485. ) AS number
  486. FROM a4
  487. ORDER BY
  488. number
  489. )
  490. SELECT
  491. RTRIM(LTRIM(
  492. SUBSTRING
  493. (
  494. @header,
  495. number + 1,
  496. CHARINDEX(CHAR(13), @header, number + 1) - number - 1
  497. )
  498. )) AS [------header---------------------------------------------------------------------------------------------------------------]
  499. FROM numbers
  500. WHERE
  501. SUBSTRING(@header, number, 1) = CHAR(13);
  502. WITH
  503. a0 AS
  504. (SELECT 1 AS n UNION ALL SELECT 1),
  505. a1 AS
  506. (SELECT 1 AS n FROM a0 AS a CROSS JOIN a0 AS b),
  507. a2 AS
  508. (SELECT 1 AS n FROM a1 AS a CROSS JOIN a1 AS b),
  509. a3 AS
  510. (SELECT 1 AS n FROM a2 AS a CROSS JOIN a2 AS b),
  511. a4 AS
  512. (SELECT 1 AS n FROM a3 AS a CROSS JOIN a3 AS b),
  513. numbers AS
  514. (
  515. SELECT TOP(LEN(@params) - 1)
  516. ROW_NUMBER() OVER
  517. (
  518. ORDER BY (SELECT NULL)
  519. ) AS number
  520. FROM a4
  521. ORDER BY
  522. number
  523. ),
  524. tokens AS
  525. (
  526. SELECT
  527. RTRIM(LTRIM(
  528. SUBSTRING
  529. (
  530. @params,
  531. number + 1,
  532. CHARINDEX(CHAR(13), @params, number + 1) - number - 1
  533. )
  534. )) AS token,
  535. number,
  536. CASE
  537. WHEN SUBSTRING(@params, number + 1, 1) = CHAR(13) THEN number
  538. ELSE COALESCE(NULLIF(CHARINDEX(',' + CHAR(13) + CHAR(13), @params, number), 0), LEN(@params))
  539. END AS param_group,
  540. ROW_NUMBER() OVER
  541. (
  542. PARTITION BY
  543. CHARINDEX(',' + CHAR(13) + CHAR(13), @params, number),
  544. SUBSTRING(@params, number+1, 1)
  545. ORDER BY
  546. number
  547. ) AS group_order
  548. FROM numbers
  549. WHERE
  550. SUBSTRING(@params, number, 1) = CHAR(13)
  551. ),
  552. parsed_tokens AS
  553. (
  554. SELECT
  555. MIN
  556. (
  557. CASE
  558. WHEN token LIKE '@%' THEN token
  559. ELSE NULL
  560. END
  561. ) AS parameter,
  562. MIN
  563. (
  564. CASE
  565. WHEN token LIKE '--%' THEN RIGHT(token, LEN(token) - 2)
  566. ELSE NULL
  567. END
  568. ) AS description,
  569. param_group,
  570. group_order
  571. FROM tokens
  572. WHERE
  573. NOT
  574. (
  575. token = ''
  576. AND group_order > 1
  577. )
  578. GROUP BY
  579. param_group,
  580. group_order
  581. )
  582. SELECT
  583. CASE
  584. WHEN description IS NULL AND parameter IS NULL THEN '-------------------------------------------------------------------------'
  585. WHEN param_group = MAX(param_group) OVER() THEN parameter
  586. ELSE COALESCE(LEFT(parameter, LEN(parameter) - 1), '')
  587. END AS [------parameter----------------------------------------------------------],
  588. CASE
  589. WHEN description IS NULL AND parameter IS NULL THEN '----------------------------------------------------------------------------------------------------------------------'
  590. ELSE COALESCE(description, '')
  591. END AS [------description-----------------------------------------------------------------------------------------------------]
  592. FROM parsed_tokens
  593. ORDER BY
  594. param_group,
  595. group_order;
  596. WITH
  597. a0 AS
  598. (SELECT 1 AS n UNION ALL SELECT 1),
  599. a1 AS
  600. (SELECT 1 AS n FROM a0 AS a CROSS JOIN a0 AS b),
  601. a2 AS
  602. (SELECT 1 AS n FROM a1 AS a CROSS JOIN a1 AS b),
  603. a3 AS
  604. (SELECT 1 AS n FROM a2 AS a CROSS JOIN a2 AS b),
  605. a4 AS
  606. (SELECT 1 AS n FROM a3 AS a CROSS JOIN a3 AS b),
  607. numbers AS
  608. (
  609. SELECT TOP(LEN(@outputs) - 1)
  610. ROW_NUMBER() OVER
  611. (
  612. ORDER BY (SELECT NULL)
  613. ) AS number
  614. FROM a4
  615. ORDER BY
  616. number
  617. ),
  618. tokens AS
  619. (
  620. SELECT
  621. RTRIM(LTRIM(
  622. SUBSTRING
  623. (
  624. @outputs,
  625. number + 1,
  626. CASE
  627. WHEN
  628. COALESCE(NULLIF(CHARINDEX(CHAR(13) + 'Formatted', @outputs, number + 1), 0), LEN(@outputs)) <
  629. COALESCE(NULLIF(CHARINDEX(CHAR(13) + CHAR(255) COLLATE Latin1_General_Bin2, @outputs, number + 1), 0), LEN(@outputs))
  630. THEN COALESCE(NULLIF(CHARINDEX(CHAR(13) + 'Formatted', @outputs, number + 1), 0), LEN(@outputs)) - number - 1
  631. ELSE
  632. COALESCE(NULLIF(CHARINDEX(CHAR(13) + CHAR(255) COLLATE Latin1_General_Bin2, @outputs, number + 1), 0), LEN(@outputs)) - number - 1
  633. END
  634. )
  635. )) AS token,
  636. number,
  637. COALESCE(NULLIF(CHARINDEX(CHAR(13) + 'Formatted', @outputs, number + 1), 0), LEN(@outputs)) AS output_group,
  638. ROW_NUMBER() OVER
  639. (
  640. PARTITION BY
  641. COALESCE(NULLIF(CHARINDEX(CHAR(13) + 'Formatted', @outputs, number + 1), 0), LEN(@outputs))
  642. ORDER BY
  643. number
  644. ) AS output_group_order
  645. FROM numbers
  646. WHERE
  647. SUBSTRING(@outputs, number, 10) = CHAR(13) + 'Formatted'
  648. OR SUBSTRING(@outputs, number, 2) = CHAR(13) + CHAR(255) COLLATE Latin1_General_Bin2
  649. ),
  650. output_tokens AS
  651. (
  652. SELECT
  653. *,
  654. CASE output_group_order
  655. WHEN 2 THEN MAX(CASE output_group_order WHEN 1 THEN token ELSE NULL END) OVER (PARTITION BY output_group)
  656. ELSE ''
  657. END COLLATE Latin1_General_Bin2 AS column_info
  658. FROM tokens
  659. )
  660. SELECT
  661. CASE output_group_order
  662. WHEN 1 THEN '-----------------------------------'
  663. WHEN 2 THEN
  664. CASE
  665. WHEN CHARINDEX('Formatted/Non:', column_info) = 1 THEN
  666. SUBSTRING(column_info, CHARINDEX(CHAR(255) COLLATE Latin1_General_Bin2, column_info)+1, CHARINDEX(']', column_info, CHARINDEX(CHAR(255) COLLATE Latin1_General_Bin2, column_info)+2) - CHARINDEX(CHAR(255) COLLATE Latin1_General_Bin2, column_info))
  667. ELSE
  668. SUBSTRING(column_info, CHARINDEX(CHAR(255) COLLATE Latin1_General_Bin2, column_info)+2, CHARINDEX(']', column_info, CHARINDEX(CHAR(255) COLLATE Latin1_General_Bin2, column_info)+2) - CHARINDEX(CHAR(255) COLLATE Latin1_General_Bin2, column_info)-1)
  669. END
  670. ELSE ''
  671. END AS formatted_column_name,
  672. CASE output_group_order
  673. WHEN 1 THEN '-----------------------------------'
  674. WHEN 2 THEN
  675. CASE
  676. WHEN CHARINDEX('Formatted/Non:', column_info) = 1 THEN
  677. SUBSTRING(column_info, CHARINDEX(']', column_info)+2, LEN(column_info))
  678. ELSE
  679. SUBSTRING(column_info, CHARINDEX(']', column_info)+2, CHARINDEX('Non-Formatted:', column_info, CHARINDEX(']', column_info)+2) - CHARINDEX(']', column_info)-3)
  680. END
  681. ELSE ''
  682. END AS formatted_column_type,
  683. CASE output_group_order
  684. WHEN 1 THEN '---------------------------------------'
  685. WHEN 2 THEN
  686. CASE
  687. WHEN CHARINDEX('Formatted/Non:', column_info) = 1 THEN ''
  688. ELSE
  689. CASE
  690. WHEN SUBSTRING(column_info, CHARINDEX(CHAR(255) COLLATE Latin1_General_Bin2, column_info, CHARINDEX('Non-Formatted:', column_info))+1, 1) = '<' THEN
  691. SUBSTRING(column_info, CHARINDEX(CHAR(255) COLLATE Latin1_General_Bin2, column_info, CHARINDEX('Non-Formatted:', column_info))+1, CHARINDEX('>', column_info, CHARINDEX(CHAR(255) COLLATE Latin1_General_Bin2, column_info, CHARINDEX('Non-Formatted:', column_info))+1) - CHARINDEX(CHAR(255) COLLATE Latin1_General_Bin2, column_info, CHARINDEX('Non-Formatted:', column_info)))
  692. ELSE
  693. SUBSTRING(column_info, CHARINDEX(CHAR(255) COLLATE Latin1_General_Bin2, column_info, CHARINDEX('Non-Formatted:', column_info))+1, CHARINDEX(']', column_info, CHARINDEX(CHAR(255) COLLATE Latin1_General_Bin2, column_info, CHARINDEX('Non-Formatted:', column_info))+1) - CHARINDEX(CHAR(255) COLLATE Latin1_General_Bin2, column_info, CHARINDEX('Non-Formatted:', column_info)))
  694. END
  695. END
  696. ELSE ''
  697. END AS unformatted_column_name,
  698. CASE output_group_order
  699. WHEN 1 THEN '---------------------------------------'
  700. WHEN 2 THEN
  701. CASE
  702. WHEN CHARINDEX('Formatted/Non:', column_info) = 1 THEN ''
  703. ELSE
  704. CASE
  705. WHEN SUBSTRING(column_info, CHARINDEX(CHAR(255) COLLATE Latin1_General_Bin2, column_info, CHARINDEX('Non-Formatted:', column_info))+1, 1) = '<' THEN ''
  706. ELSE
  707. SUBSTRING(column_info, CHARINDEX(']', column_info, CHARINDEX('Non-Formatted:', column_info))+2, CHARINDEX('Non-Formatted:', column_info, CHARINDEX(']', column_info)+2) - CHARINDEX(']', column_info)-3)
  708. END
  709. END
  710. ELSE ''
  711. END AS unformatted_column_type,
  712. CASE output_group_order
  713. WHEN 1 THEN '----------------------------------------------------------------------------------------------------------------------'
  714. ELSE REPLACE(token, CHAR(255) COLLATE Latin1_General_Bin2, '')
  715. END AS [------description-----------------------------------------------------------------------------------------------------]
  716. FROM output_tokens
  717. WHERE
  718. NOT
  719. (
  720. output_group_order = 1
  721. AND output_group = LEN(@outputs)
  722. )
  723. ORDER BY
  724. output_group,
  725. CASE output_group_order
  726. WHEN 1 THEN 99
  727. ELSE output_group_order
  728. END;
  729. RETURN;
  730. END;
  731. WITH
  732. a0 AS
  733. (SELECT 1 AS n UNION ALL SELECT 1),
  734. a1 AS
  735. (SELECT 1 AS n FROM a0 AS a CROSS JOIN a0 AS b),
  736. a2 AS
  737. (SELECT 1 AS n FROM a1 AS a CROSS JOIN a1 AS b),
  738. a3 AS
  739. (SELECT 1 AS n FROM a2 AS a CROSS JOIN a2 AS b),
  740. a4 AS
  741. (SELECT 1 AS n FROM a3 AS a CROSS JOIN a3 AS b),
  742. numbers AS
  743. (
  744. SELECT TOP(LEN(@output_column_list))
  745. ROW_NUMBER() OVER
  746. (
  747. ORDER BY (SELECT NULL)
  748. ) AS number
  749. FROM a4
  750. ORDER BY
  751. number
  752. ),
  753. tokens AS
  754. (
  755. SELECT
  756. '|[' +
  757. SUBSTRING
  758. (
  759. @output_column_list,
  760. number + 1,
  761. CHARINDEX(']', @output_column_list, number) - number - 1
  762. ) + '|]' AS token,
  763. number
  764. FROM numbers
  765. WHERE
  766. SUBSTRING(@output_column_list, number, 1) = '['
  767. ),
  768. ordered_columns AS
  769. (
  770. SELECT
  771. x.column_name,
  772. ROW_NUMBER() OVER
  773. (
  774. PARTITION BY
  775. x.column_name
  776. ORDER BY
  777. tokens.number,
  778. x.default_order
  779. ) AS r,
  780. ROW_NUMBER() OVER
  781. (
  782. ORDER BY
  783. tokens.number,
  784. x.default_order
  785. ) AS s
  786. FROM tokens
  787. JOIN
  788. (
  789. SELECT '[session_id]' AS column_name, 1 AS default_order
  790. UNION ALL
  791. SELECT '[dd hh:mm:ss.mss]', 2
  792. WHERE
  793. @format_output IN (1, 2)
  794. UNION ALL
  795. SELECT '[dd hh:mm:ss.mss (avg)]', 3
  796. WHERE
  797. @format_output IN (1, 2)
  798. AND @get_avg_time = 1
  799. UNION ALL
  800. SELECT '[avg_elapsed_time]', 4
  801. WHERE
  802. @format_output = 0
  803. AND @get_avg_time = 1
  804. UNION ALL
  805. SELECT '[physical_io]', 5
  806. WHERE
  807. @get_task_info = 2
  808. UNION ALL
  809. SELECT '[reads]', 6
  810. UNION ALL
  811. SELECT '[physical_reads]', 7
  812. UNION ALL
  813. SELECT '[writes]', 8
  814. UNION ALL
  815. SELECT '[tempdb_allocations]', 9
  816. UNION ALL
  817. SELECT '[tempdb_current]', 10
  818. UNION ALL
  819. SELECT '[CPU]', 11
  820. UNION ALL
  821. SELECT '[context_switches]', 12
  822. WHERE
  823. @get_task_info = 2
  824. UNION ALL
  825. SELECT '[used_memory]', 13
  826. UNION ALL
  827. SELECT '[physical_io_delta]', 14
  828. WHERE
  829. @delta_interval > 0
  830. AND @get_task_info = 2
  831. UNION ALL
  832. SELECT '[reads_delta]', 15
  833. WHERE
  834. @delta_interval > 0
  835. UNION ALL
  836. SELECT '[physical_reads_delta]', 16
  837. WHERE
  838. @delta_interval > 0
  839. UNION ALL
  840. SELECT '[writes_delta]', 17
  841. WHERE
  842. @delta_interval > 0
  843. UNION ALL
  844. SELECT '[tempdb_allocations_delta]', 18
  845. WHERE
  846. @delta_interval > 0
  847. UNION ALL
  848. SELECT '[tempdb_current_delta]', 19
  849. WHERE
  850. @delta_interval > 0
  851. UNION ALL
  852. SELECT '[CPU_delta]', 20
  853. WHERE
  854. @delta_interval > 0
  855. UNION ALL
  856. SELECT '[context_switches_delta]', 21
  857. WHERE
  858. @delta_interval > 0
  859. AND @get_task_info = 2
  860. UNION ALL
  861. SELECT '[used_memory_delta]', 22
  862. WHERE
  863. @delta_interval > 0
  864. UNION ALL
  865. SELECT '[tasks]', 23
  866. WHERE
  867. @get_task_info = 2
  868. UNION ALL
  869. SELECT '[status]', 24
  870. UNION ALL
  871. SELECT '[wait_info]', 25
  872. WHERE
  873. @get_task_info > 0
  874. OR @find_block_leaders = 1
  875. UNION ALL
  876. SELECT '[locks]', 26
  877. WHERE
  878. @get_locks = 1
  879. UNION ALL
  880. SELECT '[tran_start_time]', 27
  881. WHERE
  882. @get_transaction_info = 1
  883. UNION ALL
  884. SELECT '[tran_log_writes]', 28
  885. WHERE
  886. @get_transaction_info = 1
  887. UNION ALL
  888. SELECT '[open_tran_count]', 29
  889. UNION ALL
  890. SELECT '[sql_command]', 30
  891. WHERE
  892. @get_outer_command = 1
  893. UNION ALL
  894. SELECT '[sql_text]', 31
  895. UNION ALL
  896. SELECT '[query_plan]', 32
  897. WHERE
  898. @get_plans >= 1
  899. UNION ALL
  900. SELECT '[blocking_session_id]', 33
  901. WHERE
  902. @get_task_info > 0
  903. OR @find_block_leaders = 1
  904. UNION ALL
  905. SELECT '[blocked_session_count]', 34
  906. WHERE
  907. @find_block_leaders = 1
  908. UNION ALL
  909. SELECT '[percent_complete]', 35
  910. UNION ALL
  911. SELECT '[host_name]', 36
  912. UNION ALL
  913. SELECT '[login_name]', 37
  914. UNION ALL
  915. SELECT '[database_name]', 38
  916. UNION ALL
  917. SELECT '[program_name]', 39
  918. UNION ALL
  919. SELECT '[additional_info]', 40
  920. WHERE
  921. @get_additional_info = 1
  922. UNION ALL
  923. SELECT '[start_time]', 41
  924. UNION ALL
  925. SELECT '[login_time]', 42
  926. UNION ALL
  927. SELECT '[request_id]', 43
  928. UNION ALL
  929. SELECT '[collection_time]', 44
  930. ) AS x ON
  931. x.column_name LIKE token ESCAPE '|'
  932. )
  933. SELECT
  934. @output_column_list =
  935. STUFF
  936. (
  937. (
  938. SELECT
  939. ',' + column_name as [text()]
  940. FROM ordered_columns
  941. WHERE
  942. r = 1
  943. ORDER BY
  944. s
  945. FOR XML
  946. PATH('')
  947. ),
  948. 1,
  949. 1,
  950. ''
  951. );
  952. IF COALESCE(RTRIM(@output_column_list), '') = ''
  953. BEGIN;
  954. RAISERROR('No valid column matches found in @output_column_list or no columns remain due to selected options.', 16, 1);
  955. RETURN;
  956. END;
  957. IF @destination_table <> ''
  958. BEGIN;
  959. SET @destination_table =
  960. --database
  961. COALESCE(QUOTENAME(PARSENAME(@destination_table, 3)) + '.', '') +
  962. --schema
  963. COALESCE(QUOTENAME(PARSENAME(@destination_table, 2)) + '.', '') +
  964. --table
  965. COALESCE(QUOTENAME(PARSENAME(@destination_table, 1)), '');
  966. IF COALESCE(RTRIM(@destination_table), '') = ''
  967. BEGIN;
  968. RAISERROR('Destination table not properly formatted.', 16, 1);
  969. RETURN;
  970. END;
  971. END;
  972. WITH
  973. a0 AS
  974. (SELECT 1 AS n UNION ALL SELECT 1),
  975. a1 AS
  976. (SELECT 1 AS n FROM a0 AS a CROSS JOIN a0 AS b),
  977. a2 AS
  978. (SELECT 1 AS n FROM a1 AS a CROSS JOIN a1 AS b),
  979. a3 AS
  980. (SELECT 1 AS n FROM a2 AS a CROSS JOIN a2 AS b),
  981. a4 AS
  982. (SELECT 1 AS n FROM a3 AS a CROSS JOIN a3 AS b),
  983. numbers AS
  984. (
  985. SELECT TOP(LEN(@sort_order))
  986. ROW_NUMBER() OVER
  987. (
  988. ORDER BY (SELECT NULL)
  989. ) AS number
  990. FROM a4
  991. ORDER BY
  992. number
  993. ),
  994. tokens AS
  995. (
  996. SELECT
  997. '|[' +
  998. SUBSTRING
  999. (
  1000. @sort_order,
  1001. number + 1,
  1002. CHARINDEX(']', @sort_order, number) - number - 1
  1003. ) + '|]' AS token,
  1004. SUBSTRING
  1005. (
  1006. @sort_order,
  1007. CHARINDEX(']', @sort_order, number) + 1,
  1008. COALESCE(NULLIF(CHARINDEX('[', @sort_order, CHARINDEX(']', @sort_order, number)), 0), LEN(@sort_order)) - CHARINDEX(']', @sort_order, number)
  1009. ) AS next_chunk,
  1010. number
  1011. FROM numbers
  1012. WHERE
  1013. SUBSTRING(@sort_order, number, 1) = '['
  1014. ),
  1015. ordered_columns AS
  1016. (
  1017. SELECT
  1018. x.column_name +
  1019. CASE
  1020. WHEN LOWER(tokens.next_chunk) LIKE '%asc%' THEN ' ASC'
  1021. WHEN LOWER(tokens.next_chunk) LIKE '%desc%' THEN ' DESC'
  1022. ELSE ''
  1023. END AS column_name,
  1024. ROW_NUMBER() OVER
  1025. (
  1026. PARTITION BY
  1027. x.column_name
  1028. ORDER BY
  1029. tokens.number
  1030. ) AS r,
  1031. tokens.number
  1032. FROM tokens
  1033. JOIN
  1034. (
  1035. SELECT '[session_id]' AS column_name
  1036. UNION ALL
  1037. SELECT '[physical_io]'
  1038. UNION ALL
  1039. SELECT '[reads]'
  1040. UNION ALL
  1041. SELECT '[physical_reads]'
  1042. UNION ALL
  1043. SELECT '[writes]'
  1044. UNION ALL
  1045. SELECT '[tempdb_allocations]'
  1046. UNION ALL
  1047. SELECT '[tempdb_current]'
  1048. UNION ALL
  1049. SELECT '[CPU]'
  1050. UNION ALL
  1051. SELECT '[context_switches]'
  1052. UNION ALL
  1053. SELECT '[used_memory]'
  1054. UNION ALL
  1055. SELECT '[physical_io_delta]'
  1056. UNION ALL
  1057. SELECT '[reads_delta]'
  1058. UNION ALL
  1059. SELECT '[physical_reads_delta]'
  1060. UNION ALL
  1061. SELECT '[writes_delta]'
  1062. UNION ALL
  1063. SELECT '[tempdb_allocations_delta]'
  1064. UNION ALL
  1065. SELECT '[tempdb_current_delta]'
  1066. UNION ALL
  1067. SELECT '[CPU_delta]'
  1068. UNION ALL
  1069. SELECT '[context_switches_delta]'
  1070. UNION ALL
  1071. SELECT '[used_memory_delta]'
  1072. UNION ALL
  1073. SELECT '[tasks]'
  1074. UNION ALL
  1075. SELECT '[tran_start_time]'
  1076. UNION ALL
  1077. SELECT '[open_tran_count]'
  1078. UNION ALL
  1079. SELECT '[blocking_session_id]'
  1080. UNION ALL
  1081. SELECT '[blocked_session_count]'
  1082. UNION ALL
  1083. SELECT '[percent_complete]'
  1084. UNION ALL
  1085. SELECT '[host_name]'
  1086. UNION ALL
  1087. SELECT '[login_name]'
  1088. UNION ALL
  1089. SELECT '[database_name]'
  1090. UNION ALL
  1091. SELECT '[start_time]'
  1092. UNION ALL
  1093. SELECT '[login_time]'
  1094. UNION ALL
  1095. SELECT '[program_name]'
  1096. ) AS x ON
  1097. x.column_name LIKE token ESCAPE '|'
  1098. )
  1099. SELECT
  1100. @sort_order = COALESCE(z.sort_order, '')
  1101. FROM
  1102. (
  1103. SELECT
  1104. STUFF
  1105. (
  1106. (
  1107. SELECT
  1108. ',' + column_name as [text()]
  1109. FROM ordered_columns
  1110. WHERE
  1111. r = 1
  1112. ORDER BY
  1113. number
  1114. FOR XML
  1115. PATH('')
  1116. ),
  1117. 1,
  1118. 1,
  1119. ''
  1120. ) AS sort_order
  1121. ) AS z;
  1122. CREATE TABLE #sessions
  1123. (
  1124. recursion SMALLINT NOT NULL,
  1125. session_id SMALLINT NOT NULL,
  1126. request_id INT NOT NULL,
  1127. session_number INT NOT NULL,
  1128. elapsed_time INT NOT NULL,
  1129. avg_elapsed_time INT NULL,
  1130. physical_io BIGINT NULL,
  1131. reads BIGINT NULL,
  1132. physical_reads BIGINT NULL,
  1133. writes BIGINT NULL,
  1134. tempdb_allocations BIGINT NULL,
  1135. tempdb_current BIGINT NULL,
  1136. CPU INT NULL,
  1137. thread_CPU_snapshot BIGINT NULL,
  1138. context_switches BIGINT NULL,
  1139. used_memory BIGINT NOT NULL,
  1140. tasks SMALLINT NULL,
  1141. status VARCHAR(30) NOT NULL,
  1142. wait_info NVARCHAR(4000) NULL,
  1143. locks XML NULL,
  1144. transaction_id BIGINT NULL,
  1145. tran_start_time DATETIME NULL,
  1146. tran_log_writes NVARCHAR(4000) NULL,
  1147. open_tran_count SMALLINT NULL,
  1148. sql_command XML NULL,
  1149. sql_handle VARBINARY(64) NULL,
  1150. statement_start_offset INT NULL,
  1151. statement_end_offset INT NULL,
  1152. sql_text XML NULL,
  1153. plan_handle VARBINARY(64) NULL,
  1154. query_plan XML NULL,
  1155. blocking_session_id SMALLINT NULL,
  1156. blocked_session_count SMALLINT NULL,
  1157. percent_complete REAL NULL,
  1158. host_name sysname NULL,
  1159. login_name sysname NOT NULL,
  1160. database_name sysname NULL,
  1161. program_name sysname NULL,
  1162. additional_info XML NULL,
  1163. start_time DATETIME NOT NULL,
  1164. login_time DATETIME NULL,
  1165. last_request_start_time DATETIME NULL,
  1166. PRIMARY KEY CLUSTERED (session_id, request_id, recursion) WITH (IGNORE_DUP_KEY = ON),
  1167. UNIQUE NONCLUSTERED (transaction_id, session_id, request_id, recursion) WITH (IGNORE_DUP_KEY = ON)
  1168. );
  1169. IF @return_schema = 0
  1170. BEGIN;
  1171. --Disable unnecessary autostats on the table
  1172. CREATE STATISTICS s_session_id ON #sessions (session_id)
  1173. WITH SAMPLE 0 ROWS, NORECOMPUTE;
  1174. CREATE STATISTICS s_request_id ON #sessions (request_id)
  1175. WITH SAMPLE 0 ROWS, NORECOMPUTE;
  1176. CREATE STATISTICS s_transaction_id ON #sessions (transaction_id)
  1177. WITH SAMPLE 0 ROWS, NORECOMPUTE;
  1178. CREATE STATISTICS s_session_number ON #sessions (session_number)
  1179. WITH SAMPLE 0 ROWS, NORECOMPUTE;
  1180. CREATE STATISTICS s_status ON #sessions (status)
  1181. WITH SAMPLE 0 ROWS, NORECOMPUTE;
  1182. CREATE STATISTICS s_start_time ON #sessions (start_time)
  1183. WITH SAMPLE 0 ROWS, NORECOMPUTE;
  1184. CREATE STATISTICS s_last_request_start_time ON #sessions (last_request_start_time)
  1185. WITH SAMPLE 0 ROWS, NORECOMPUTE;
  1186. CREATE STATISTICS s_recursion ON #sessions (recursion)
  1187. WITH SAMPLE 0 ROWS, NORECOMPUTE;
  1188. DECLARE @recursion SMALLINT;
  1189. SET @recursion =
  1190. CASE @delta_interval
  1191. WHEN 0 THEN 1
  1192. ELSE -1
  1193. END;
  1194. DECLARE @first_collection_ms_ticks BIGINT;
  1195. DECLARE @last_collection_start DATETIME;
  1196. DECLARE @sys_info BIT;
  1197. SET @sys_info = ISNULL(CONVERT(BIT, SIGN(OBJECT_ID('sys.dm_os_sys_info'))), 0);
  1198. --Used for the delta pull
  1199. REDO:;
  1200. IF
  1201. @get_locks = 1
  1202. AND @recursion = 1
  1203. AND @output_column_list LIKE '%|[locks|]%' ESCAPE '|'
  1204. BEGIN;
  1205. SELECT
  1206. y.resource_type,
  1207. y.database_name,
  1208. y.object_id,
  1209. y.file_id,
  1210. y.page_type,
  1211. y.hobt_id,
  1212. y.allocation_unit_id,
  1213. y.index_id,
  1214. y.schema_id,
  1215. y.principal_id,
  1216. y.request_mode,
  1217. y.request_status,
  1218. y.session_id,
  1219. y.resource_description,
  1220. y.request_count,
  1221. s.request_id,
  1222. s.start_time,
  1223. CONVERT(sysname, NULL) AS object_name,
  1224. CONVERT(sysname, NULL) AS index_name,
  1225. CONVERT(sysname, NULL) AS schema_name,
  1226. CONVERT(sysname, NULL) AS principal_name,
  1227. CONVERT(NVARCHAR(2048), NULL) AS query_error
  1228. INTO #locks
  1229. FROM
  1230. (
  1231. SELECT
  1232. sp.spid AS session_id,
  1233. CASE sp.status
  1234. WHEN 'sleeping' THEN CONVERT(INT, 0)
  1235. ELSE sp.request_id
  1236. END AS request_id,
  1237. CASE sp.status
  1238. WHEN 'sleeping' THEN sp.last_batch
  1239. ELSE COALESCE(req.start_time, sp.last_batch)
  1240. END AS start_time,
  1241. sp.dbid
  1242. FROM sys.sysprocesses AS sp
  1243. OUTER APPLY
  1244. (
  1245. SELECT TOP(1)
  1246. CASE
  1247. WHEN
  1248. (
  1249. sp.hostprocess > ''
  1250. OR r.total_elapsed_time < 0
  1251. ) THEN
  1252. r.start_time
  1253. ELSE
  1254. DATEADD
  1255. (
  1256. ms,
  1257. 1000 * (DATEPART(ms, DATEADD(second, -(r.total_elapsed_time / 1000), GETDATE())) / 500) - DATEPART(ms, DATEADD(second, -(r.total_elapsed_time / 1000), GETDATE())),
  1258. DATEADD(second, -(r.total_elapsed_time / 1000), GETDATE())
  1259. )
  1260. END AS start_time
  1261. FROM sys.dm_exec_requests AS r
  1262. WHERE
  1263. r.session_id = sp.spid
  1264. AND r.request_id = sp.request_id
  1265. ) AS req
  1266. WHERE
  1267. --Process inclusive filter
  1268. 1 =
  1269. CASE
  1270. WHEN @filter <> '' THEN
  1271. CASE @filter_type
  1272. WHEN 'session' THEN
  1273. CASE
  1274. WHEN
  1275. CONVERT(SMALLINT, @filter) = 0
  1276. OR sp.spid = CONVERT(SMALLINT, @filter)
  1277. THEN 1
  1278. ELSE 0
  1279. END
  1280. WHEN 'program' THEN
  1281. CASE
  1282. WHEN sp.program_name LIKE @filter THEN 1
  1283. ELSE 0
  1284. END
  1285. WHEN 'login' THEN
  1286. CASE
  1287. WHEN sp.loginame LIKE @filter THEN 1
  1288. ELSE 0
  1289. END
  1290. WHEN 'host' THEN
  1291. CASE
  1292. WHEN sp.hostname LIKE @filter THEN 1
  1293. ELSE 0
  1294. END
  1295. WHEN 'database' THEN
  1296. CASE
  1297. WHEN DB_NAME(sp.dbid) LIKE @filter THEN 1
  1298. ELSE 0
  1299. END
  1300. ELSE 0
  1301. END
  1302. ELSE 1
  1303. END
  1304. --Process exclusive filter
  1305. AND 0 =
  1306. CASE
  1307. WHEN @not_filter <> '' THEN
  1308. CASE @not_filter_type
  1309. WHEN 'session' THEN
  1310. CASE
  1311. WHEN sp.spid = CONVERT(SMALLINT, @not_filter) THEN 1
  1312. ELSE 0
  1313. END
  1314. WHEN 'program' THEN
  1315. CASE
  1316. WHEN sp.program_name LIKE @not_filter THEN 1
  1317. ELSE 0
  1318. END
  1319. WHEN 'login' THEN
  1320. CASE
  1321. WHEN sp.loginame LIKE @not_filter THEN 1
  1322. ELSE 0
  1323. END
  1324. WHEN 'host' THEN
  1325. CASE
  1326. WHEN sp.hostname LIKE @not_filter THEN 1
  1327. ELSE 0
  1328. END
  1329. WHEN 'database' THEN
  1330. CASE
  1331. WHEN DB_NAME(sp.dbid) LIKE @not_filter THEN 1
  1332. ELSE 0
  1333. END
  1334. ELSE 0
  1335. END
  1336. ELSE 0
  1337. END
  1338. AND
  1339. (
  1340. @show_own_spid = 1
  1341. OR sp.spid <> @@SPID
  1342. )
  1343. AND
  1344. (
  1345. @show_system_spids = 1
  1346. OR sp.hostprocess > ''
  1347. )
  1348. AND sp.ecid = 0
  1349. ) AS s
  1350. INNER HASH JOIN
  1351. (
  1352. SELECT
  1353. x.resource_type,
  1354. x.database_name,
  1355. x.object_id,
  1356. x.file_id,
  1357. CASE
  1358. WHEN x.page_no = 1 OR x.page_no % 8088 = 0 THEN 'PFS'
  1359. WHEN x.page_no = 2 OR x.page_no % 511232 = 0 THEN 'GAM'
  1360. WHEN x.page_no = 3 OR (x.page_no - 1) % 511232 = 0 THEN 'SGAM'
  1361. WHEN x.page_no = 6 OR (x.page_no - 6) % 511232 = 0 THEN 'DCM'
  1362. WHEN x.page_no = 7 OR (x.page_no - 7) % 511232 = 0 THEN 'BCM'
  1363. WHEN x.page_no IS NOT NULL THEN '*'
  1364. ELSE NULL
  1365. END AS page_type,
  1366. x.hobt_id,
  1367. x.allocation_unit_id,
  1368. x.index_id,
  1369. x.schema_id,
  1370. x.principal_id,
  1371. x.request_mode,
  1372. x.request_status,
  1373. x.session_id,
  1374. x.request_id,
  1375. CASE
  1376. WHEN COALESCE(x.object_id, x.file_id, x.hobt_id, x.allocation_unit_id, x.index_id, x.schema_id, x.principal_id) IS NULL THEN NULLIF(resource_description, '')
  1377. ELSE NULL
  1378. END AS resource_description,
  1379. COUNT(*) AS request_count
  1380. FROM
  1381. (
  1382. SELECT
  1383. tl.resource_type +
  1384. CASE
  1385. WHEN tl.resource_subtype = '' THEN ''
  1386. ELSE '.' + tl.resource_subtype
  1387. END AS resource_type,
  1388. COALESCE(DB_NAME(tl.resource_database_id), N'(null)') AS database_name,
  1389. CONVERT
  1390. (
  1391. INT,
  1392. CASE
  1393. WHEN tl.resource_type = 'OBJECT' THEN tl.resource_associated_entity_id
  1394. WHEN tl.resource_description LIKE '%object_id = %' THEN
  1395. (
  1396. SUBSTRING
  1397. (
  1398. tl.resource_description,
  1399. (CHARINDEX('object_id = ', tl.resource_description) + 12),
  1400. COALESCE
  1401. (
  1402. NULLIF
  1403. (
  1404. CHARINDEX(',', tl.resource_description, CHARINDEX('object_id = ', tl.resource_description) + 12),
  1405. 0
  1406. ),
  1407. DATALENGTH(tl.resource_description)+1
  1408. ) - (CHARINDEX('object_id = ', tl.resource_description) + 12)
  1409. )
  1410. )
  1411. ELSE NULL
  1412. END
  1413. ) AS object_id,
  1414. CONVERT
  1415. (
  1416. INT,
  1417. CASE
  1418. WHEN tl.resource_type = 'FILE' THEN CONVERT(INT, tl.resource_description)
  1419. WHEN tl.resource_type IN ('PAGE', 'EXTENT', 'RID') THEN LEFT(tl.resource_description, CHARINDEX(':', tl.resource_description)-1)
  1420. ELSE NULL
  1421. END
  1422. ) AS file_id,
  1423. CONVERT
  1424. (
  1425. INT,
  1426. CASE
  1427. WHEN tl.resource_type IN ('PAGE', 'EXTENT', 'RID') THEN
  1428. SUBSTRING
  1429. (
  1430. tl.resource_description,
  1431. CHARINDEX(':', tl.resource_description) + 1,
  1432. COALESCE
  1433. (
  1434. NULLIF
  1435. (
  1436. CHARINDEX(':', tl.resource_description, CHARINDEX(':', tl.resource_description) + 1),
  1437. 0
  1438. ),
  1439. DATALENGTH(tl.resource_description)+1
  1440. ) - (CHARINDEX(':', tl.resource_description) + 1)
  1441. )
  1442. ELSE NULL
  1443. END
  1444. ) AS page_no,
  1445. CASE
  1446. WHEN tl.resource_type IN ('PAGE', 'KEY', 'RID', 'HOBT') THEN tl.resource_associated_entity_id
  1447. ELSE NULL
  1448. END AS hobt_id,
  1449. CASE
  1450. WHEN tl.resource_type = 'ALLOCATION_UNIT' THEN tl.resource_associated_entity_id
  1451. ELSE NULL
  1452. END AS allocation_unit_id,
  1453. CONVERT
  1454. (
  1455. INT,
  1456. CASE
  1457. WHEN
  1458. /*TODO: Deal with server principals*/
  1459. tl.resource_subtype <> 'SERVER_PRINCIPAL'
  1460. AND tl.resource_description LIKE '%index_id or stats_id = %' THEN
  1461. (
  1462. SUBSTRING
  1463. (
  1464. tl.resource_description,
  1465. (CHARINDEX('index_id or stats_id = ', tl.resource_description) + 23),
  1466. COALESCE
  1467. (
  1468. NULLIF
  1469. (
  1470. CHARINDEX(',', tl.resource_description, CHARINDEX('index_id or stats_id = ', tl.resource_description) + 23),
  1471. 0
  1472. ),
  1473. DATALENGTH(tl.resource_description)+1
  1474. ) - (CHARINDEX('index_id or stats_id = ', tl.resource_description) + 23)
  1475. )
  1476. )
  1477. ELSE NULL
  1478. END
  1479. ) AS index_id,
  1480. CONVERT
  1481. (
  1482. INT,
  1483. CASE
  1484. WHEN tl.resource_description LIKE '%schema_id = %' THEN
  1485. (
  1486. SUBSTRING
  1487. (
  1488. tl.resource_description,
  1489. (CHARINDEX('schema_id = ', tl.resource_description) + 12),
  1490. COALESCE
  1491. (
  1492. NULLIF
  1493. (
  1494. CHARINDEX(',', tl.resource_description, CHARINDEX('schema_id = ', tl.resource_description) + 12),
  1495. 0
  1496. ),
  1497. DATALENGTH(tl.resource_description)+1
  1498. ) - (CHARINDEX('schema_id = ', tl.resource_description) + 12)
  1499. )
  1500. )
  1501. ELSE NULL
  1502. END
  1503. ) AS schema_id,
  1504. CONVERT
  1505. (
  1506. INT,
  1507. CASE
  1508. WHEN tl.resource_description LIKE '%principal_id = %' THEN
  1509. (
  1510. SUBSTRING
  1511. (
  1512. tl.resource_description,
  1513. (CHARINDEX('principal_id = ', tl.resource_description) + 15),
  1514. COALESCE
  1515. (
  1516. NULLIF
  1517. (
  1518. CHARINDEX(',', tl.resource_description, CHARINDEX('principal_id = ', tl.resource_description) + 15),
  1519. 0
  1520. ),
  1521. DATALENGTH(tl.resource_description)+1
  1522. ) - (CHARINDEX('principal_id = ', tl.resource_description) + 15)
  1523. )
  1524. )
  1525. ELSE NULL
  1526. END
  1527. ) AS principal_id,
  1528. tl.request_mode,
  1529. tl.request_status,
  1530. tl.request_session_id AS session_id,
  1531. tl.request_request_id AS request_id,
  1532. /*TODO: Applocks, other resource_descriptions*/
  1533. RTRIM(tl.resource_description) AS resource_description,
  1534. tl.resource_associated_entity_id
  1535. /*********************************************/
  1536. FROM
  1537. (
  1538. SELECT
  1539. request_session_id,
  1540. CONVERT(VARCHAR(120), resource_type) COLLATE Latin1_General_Bin2 AS resource_type,
  1541. CONVERT(VARCHAR(120), resource_subtype) COLLATE Latin1_General_Bin2 AS resource_subtype,
  1542. resource_database_id,
  1543. CONVERT(VARCHAR(512), resource_description) COLLATE Latin1_General_Bin2 AS resource_description,
  1544. resource_associated_entity_id,
  1545. CONVERT(VARCHAR(120), request_mode) COLLATE Latin1_General_Bin2 AS request_mode,
  1546. CONVERT(VARCHAR(120), request_status) COLLATE Latin1_General_Bin2 AS request_status,
  1547. request_request_id
  1548. FROM sys.dm_tran_locks
  1549. ) AS tl
  1550. ) AS x
  1551. GROUP BY
  1552. x.resource_type,
  1553. x.database_name,
  1554. x.object_id,
  1555. x.file_id,
  1556. CASE
  1557. WHEN x.page_no = 1 OR x.page_no % 8088 = 0 THEN 'PFS'
  1558. WHEN x.page_no = 2 OR x.page_no % 511232 = 0 THEN 'GAM'
  1559. WHEN x.page_no = 3 OR (x.page_no - 1) % 511232 = 0 THEN 'SGAM'
  1560. WHEN x.page_no = 6 OR (x.page_no - 6) % 511232 = 0 THEN 'DCM'
  1561. WHEN x.page_no = 7 OR (x.page_no - 7) % 511232 = 0 THEN 'BCM'
  1562. WHEN x.page_no IS NOT NULL THEN '*'
  1563. ELSE NULL
  1564. END,
  1565. x.hobt_id,
  1566. x.allocation_unit_id,
  1567. x.index_id,
  1568. x.schema_id,
  1569. x.principal_id,
  1570. x.request_mode,
  1571. x.request_status,
  1572. x.session_id,
  1573. x.request_id,
  1574. CASE
  1575. WHEN COALESCE(x.object_id, x.file_id, x.hobt_id, x.allocation_unit_id, x.index_id, x.schema_id, x.principal_id) IS NULL THEN NULLIF(resource_description, '')
  1576. ELSE NULL
  1577. END
  1578. ) AS y ON
  1579. y.session_id = s.session_id
  1580. AND y.request_id = s.request_id
  1581. OPTION (HASH GROUP);
  1582. --Disable unnecessary autostats on the table
  1583. CREATE STATISTICS s_database_name ON #locks (database_name)
  1584. WITH SAMPLE 0 ROWS, NORECOMPUTE;
  1585. CREATE STATISTICS s_object_id ON #locks (object_id)
  1586. WITH SAMPLE 0 ROWS, NORECOMPUTE;
  1587. CREATE STATISTICS s_hobt_id ON #locks (hobt_id)
  1588. WITH SAMPLE 0 ROWS, NORECOMPUTE;
  1589. CREATE STATISTICS s_allocation_unit_id ON #locks (allocation_unit_id)
  1590. WITH SAMPLE 0 ROWS, NORECOMPUTE;
  1591. CREATE STATISTICS s_index_id ON #locks (index_id)
  1592. WITH SAMPLE 0 ROWS, NORECOMPUTE;
  1593. CREATE STATISTICS s_schema_id ON #locks (schema_id)
  1594. WITH SAMPLE 0 ROWS, NORECOMPUTE;
  1595. CREATE STATISTICS s_principal_id ON #locks (principal_id)
  1596. WITH SAMPLE 0 ROWS, NORECOMPUTE;
  1597. CREATE STATISTICS s_request_id ON #locks (request_id)
  1598. WITH SAMPLE 0 ROWS, NORECOMPUTE;
  1599. CREATE STATISTICS s_start_time ON #locks (start_time)
  1600. WITH SAMPLE 0 ROWS, NORECOMPUTE;
  1601. CREATE STATISTICS s_resource_type ON #locks (resource_type)
  1602. WITH SAMPLE 0 ROWS, NORECOMPUTE;
  1603. CREATE STATISTICS s_object_name ON #locks (object_name)
  1604. WITH SAMPLE 0 ROWS, NORECOMPUTE;
  1605. CREATE STATISTICS s_schema_name ON #locks (schema_name)
  1606. WITH SAMPLE 0 ROWS, NORECOMPUTE;
  1607. CREATE STATISTICS s_page_type ON #locks (page_type)
  1608. WITH SAMPLE 0 ROWS, NORECOMPUTE;
  1609. CREATE STATISTICS s_request_mode ON #locks (request_mode)
  1610. WITH SAMPLE 0 ROWS, NORECOMPUTE;
  1611. CREATE STATISTICS s_request_status ON #locks (request_status)
  1612. WITH SAMPLE 0 ROWS, NORECOMPUTE;
  1613. CREATE STATISTICS s_resource_description ON #locks (resource_description)
  1614. WITH SAMPLE 0 ROWS, NORECOMPUTE;
  1615. CREATE STATISTICS s_index_name ON #locks (index_name)
  1616. WITH SAMPLE 0 ROWS, NORECOMPUTE;
  1617. CREATE STATISTICS s_principal_name ON #locks (principal_name)
  1618. WITH SAMPLE 0 ROWS, NORECOMPUTE;
  1619. END;
  1620. DECLARE
  1621. @sql VARCHAR(MAX),
  1622. @sql_n NVARCHAR(MAX);
  1623. SET @sql =
  1624. CONVERT(VARCHAR(MAX), '') +
  1625. 'DECLARE @blocker BIT;
  1626. SET @blocker = 0;
  1627. DECLARE @i INT;
  1628. SET @i = 2147483647;
  1629. DECLARE @sessions TABLE
  1630. (
  1631. session_id SMALLINT NOT NULL,
  1632. request_id INT NOT NULL,
  1633. login_time DATETIME,
  1634. last_request_end_time DATETIME,
  1635. status VARCHAR(30),
  1636. statement_start_offset INT,
  1637. statement_end_offset INT,
  1638. sql_handle BINARY(20),
  1639. host_name NVARCHAR(128),
  1640. login_name NVARCHAR(128),
  1641. program_name NVARCHAR(128),
  1642. database_id SMALLINT,
  1643. memory_usage INT,
  1644. open_tran_count SMALLINT,
  1645. ' +
  1646. CASE
  1647. WHEN
  1648. (
  1649. @get_task_info <> 0
  1650. OR @find_block_leaders = 1
  1651. ) THEN
  1652. 'wait_type NVARCHAR(32),
  1653. wait_resource NVARCHAR(256),
  1654. wait_time BIGINT,
  1655. '
  1656. ELSE
  1657. ''
  1658. END +
  1659. 'blocked SMALLINT,
  1660. is_user_process BIT,
  1661. cmd VARCHAR(32),
  1662. PRIMARY KEY CLUSTERED (session_id, request_id) WITH (IGNORE_DUP_KEY = ON)
  1663. );
  1664. DECLARE @blockers TABLE
  1665. (
  1666. session_id INT NOT NULL PRIMARY KEY WITH (IGNORE_DUP_KEY = ON)
  1667. );
  1668. BLOCKERS:;
  1669. INSERT @sessions
  1670. (
  1671. session_id,
  1672. request_id,
  1673. login_time,
  1674. last_request_end_time,
  1675. status,
  1676. statement_start_offset,
  1677. statement_end_offset,
  1678. sql_handle,
  1679. host_name,
  1680. login_name,
  1681. program_name,
  1682. database_id,
  1683. memory_usage,
  1684. open_tran_count,
  1685. ' +
  1686. CASE
  1687. WHEN
  1688. (
  1689. @get_task_info <> 0
  1690. OR @find_block_leaders = 1
  1691. ) THEN
  1692. 'wait_type,
  1693. wait_resource,
  1694. wait_time,
  1695. '
  1696. ELSE
  1697. ''
  1698. END +
  1699. 'blocked,
  1700. is_user_process,
  1701. cmd
  1702. )
  1703. SELECT TOP(@i)
  1704. spy.session_id,
  1705. spy.request_id,
  1706. spy.login_time,
  1707. spy.last_request_end_time,
  1708. spy.status,
  1709. spy.statement_start_offset,
  1710. spy.statement_end_offset,
  1711. spy.sql_handle,
  1712. spy.host_name,
  1713. spy.login_name,
  1714. spy.program_name,
  1715. spy.database_id,
  1716. spy.memory_usage,
  1717. spy.open_tran_count,
  1718. ' +
  1719. CASE
  1720. WHEN
  1721. (
  1722. @get_task_info <> 0
  1723. OR @find_block_leaders = 1
  1724. ) THEN
  1725. 'spy.wait_type,
  1726. CASE
  1727. WHEN
  1728. spy.wait_type LIKE N''PAGE%LATCH_%''
  1729. OR spy.wait_type = N''CXPACKET''
  1730. OR spy.wait_type LIKE N''LATCH[_]%''
  1731. OR spy.wait_type = N''OLEDB'' THEN
  1732. spy.wait_resource
  1733. ELSE
  1734. NULL
  1735. END AS wait_resource,
  1736. spy.wait_time,
  1737. '
  1738. ELSE
  1739. ''
  1740. END +
  1741. 'spy.blocked,
  1742. spy.is_user_process,
  1743. spy.cmd
  1744. FROM
  1745. (
  1746. SELECT TOP(@i)
  1747. spx.*,
  1748. ' +
  1749. CASE
  1750. WHEN
  1751. (
  1752. @get_task_info <> 0
  1753. OR @find_block_leaders = 1
  1754. ) THEN
  1755. 'ROW_NUMBER() OVER
  1756. (
  1757. PARTITION BY
  1758. spx.session_id,
  1759. spx.request_id
  1760. ORDER BY
  1761. CASE
  1762. WHEN spx.wait_type LIKE N''LCK[_]%'' THEN
  1763. 1
  1764. ELSE
  1765. 99
  1766. END,
  1767. spx.wait_time DESC,
  1768. spx.blocked DESC
  1769. ) AS r
  1770. '
  1771. ELSE
  1772. '1 AS r
  1773. '
  1774. END +
  1775. 'FROM
  1776. (
  1777. SELECT TOP(@i)
  1778. sp0.session_id,
  1779. sp0.request_id,
  1780. sp0.login_time,
  1781. sp0.last_request_end_time,
  1782. LOWER(sp0.status) AS status,
  1783. CASE
  1784. WHEN sp0.cmd = ''CREATE INDEX'' THEN
  1785. 0
  1786. ELSE
  1787. sp0.stmt_start
  1788. END AS statement_start_offset,
  1789. CASE
  1790. WHEN sp0.cmd = N''CREATE INDEX'' THEN
  1791. -1
  1792. ELSE
  1793. COALESCE(NULLIF(sp0.stmt_end, 0), -1)
  1794. END AS statement_end_offset,
  1795. sp0.sql_handle,
  1796. sp0.host_name,
  1797. sp0.login_name,
  1798. sp0.program_name,
  1799. sp0.database_id,
  1800. sp0.memory_usage,
  1801. sp0.open_tran_count,
  1802. ' +
  1803. CASE
  1804. WHEN
  1805. (
  1806. @get_task_info <> 0
  1807. OR @find_block_leaders = 1
  1808. ) THEN
  1809. 'CASE
  1810. WHEN sp0.wait_time > 0 AND sp0.wait_type <> N''CXPACKET'' THEN
  1811. sp0.wait_type
  1812. ELSE
  1813. NULL
  1814. END AS wait_type,
  1815. CASE
  1816. WHEN sp0.wait_time > 0 AND sp0.wait_type <> N''CXPACKET'' THEN
  1817. sp0.wait_resource
  1818. ELSE
  1819. NULL
  1820. END AS wait_resource,
  1821. CASE
  1822. WHEN sp0.wait_type <> N''CXPACKET'' THEN
  1823. sp0.wait_time
  1824. ELSE
  1825. 0
  1826. END AS wait_time,
  1827. '
  1828. ELSE
  1829. ''
  1830. END +
  1831. 'sp0.blocked,
  1832. sp0.is_user_process,
  1833. sp0.cmd
  1834. FROM
  1835. (
  1836. SELECT TOP(@i)
  1837. sp1.session_id,
  1838. sp1.request_id,
  1839. sp1.login_time,
  1840. sp1.last_request_end_time,
  1841. sp1.status,
  1842. sp1.cmd,
  1843. sp1.stmt_start,
  1844. sp1.stmt_end,
  1845. MAX(NULLIF(sp1.sql_handle, 0x00)) OVER (PARTITION BY sp1.session_id, sp1.request_id) AS sql_handle,
  1846. sp1.host_name,
  1847. MAX(sp1.login_name) OVER (PARTITION BY sp1.session_id, sp1.request_id) AS login_name,
  1848. sp1.program_name,
  1849. sp1.database_id,
  1850. MAX(sp1.memory_usage) OVER (PARTITION BY sp1.session_id, sp1.request_id) AS memory_usage,
  1851. MAX(sp1.open_tran_count) OVER (PARTITION BY sp1.session_id, sp1.request_id) AS open_tran_count,
  1852. sp1.wait_type,
  1853. sp1.wait_resource,
  1854. sp1.wait_time,
  1855. sp1.blocked,
  1856. sp1.hostprocess,
  1857. sp1.is_user_process
  1858. FROM
  1859. (
  1860. SELECT TOP(@i)
  1861. sp2.spid AS session_id,
  1862. CASE sp2.status
  1863. WHEN ''sleeping'' THEN
  1864. CONVERT(INT, 0)
  1865. ELSE
  1866. sp2.request_id
  1867. END AS request_id,
  1868. MAX(sp2.login_time) AS login_time,
  1869. MAX(sp2.last_batch) AS last_request_end_time,
  1870. MAX(CONVERT(VARCHAR(30), RTRIM(sp2.status)) COLLATE Latin1_General_Bin2) AS status,
  1871. MAX(CONVERT(VARCHAR(32), RTRIM(sp2.cmd)) COLLATE Latin1_General_Bin2) AS cmd,
  1872. MAX(sp2.stmt_start) AS stmt_start,
  1873. MAX(sp2.stmt_end) AS stmt_end,
  1874. MAX(sp2.sql_handle) AS sql_handle,
  1875. MAX(CONVERT(sysname, RTRIM(sp2.hostname)) COLLATE SQL_Latin1_General_CP1_CI_AS) AS host_name,
  1876. MAX(CONVERT(sysname, RTRIM(sp2.loginame)) COLLATE SQL_Latin1_General_CP1_CI_AS) AS login_name,
  1877. MAX
  1878. (
  1879. CASE
  1880. WHEN blk.queue_id IS NOT NULL THEN
  1881. N''Service Broker
  1882. database_id: '' + CONVERT(NVARCHAR, blk.database_id) +
  1883. N'' queue_id: '' + CONVERT(NVARCHAR, blk.queue_id)
  1884. ELSE
  1885. CONVERT
  1886. (
  1887. sysname,
  1888. RTRIM(sp2.program_name)
  1889. )
  1890. END COLLATE SQL_Latin1_General_CP1_CI_AS
  1891. ) AS program_name,
  1892. MAX(sp2.dbid) AS database_id,
  1893. MAX(sp2.memusage) AS memory_usage,
  1894. MAX(sp2.open_tran) AS open_tran_count,
  1895. RTRIM(sp2.lastwaittype) AS wait_type,
  1896. RTRIM(sp2.waitresource) AS wait_resource,
  1897. MAX(sp2.waittime) AS wait_time,
  1898. COALESCE(NULLIF(sp2.blocked, sp2.spid), 0) AS blocked,
  1899. MAX
  1900. (
  1901. CASE
  1902. WHEN blk.session_id = sp2.spid THEN
  1903. ''blocker''
  1904. ELSE
  1905. RTRIM(sp2.hostprocess)
  1906. END
  1907. ) AS hostprocess,
  1908. CONVERT
  1909. (
  1910. BIT,
  1911. MAX
  1912. (
  1913. CASE
  1914. WHEN sp2.hostprocess > '''' THEN
  1915. 1
  1916. ELSE
  1917. 0
  1918. END
  1919. )
  1920. ) AS is_user_process
  1921. FROM
  1922. (
  1923. SELECT TOP(@i)
  1924. session_id,
  1925. CONVERT(INT, NULL) AS queue_id,
  1926. CONVERT(INT, NULL) AS database_id
  1927. FROM @blockers
  1928. UNION ALL
  1929. SELECT TOP(@i)
  1930. CONVERT(SMALLINT, 0),
  1931. CONVERT(INT, NULL) AS queue_id,
  1932. CONVERT(INT, NULL) AS database_id
  1933. WHERE
  1934. @blocker = 0
  1935. UNION ALL
  1936. SELECT TOP(@i)
  1937. CONVERT(SMALLINT, spid),
  1938. queue_id,
  1939. database_id
  1940. FROM sys.dm_broker_activated_tasks
  1941. WHERE
  1942. @blocker = 0
  1943. ) AS blk
  1944. INNER JOIN sys.sysprocesses AS sp2 ON
  1945. sp2.spid = blk.session_id
  1946. OR
  1947. (
  1948. blk.session_id = 0
  1949. AND @blocker = 0
  1950. )
  1951. ' +
  1952. CASE
  1953. WHEN
  1954. (
  1955. @get_task_info = 0
  1956. AND @find_block_leaders = 0
  1957. ) THEN
  1958. 'WHERE
  1959. sp2.ecid = 0
  1960. '
  1961. ELSE
  1962. ''
  1963. END +
  1964. 'GROUP BY
  1965. sp2.spid,
  1966. CASE sp2.status
  1967. WHEN ''sleeping'' THEN
  1968. CONVERT(INT, 0)
  1969. ELSE
  1970. sp2.request_id
  1971. END,
  1972. RTRIM(sp2.lastwaittype),
  1973. RTRIM(sp2.waitresource),
  1974. COALESCE(NULLIF(sp2.blocked, sp2.spid), 0)
  1975. ) AS sp1
  1976. ) AS sp0
  1977. WHERE
  1978. @blocker = 1
  1979. OR
  1980. (1=1
  1981. ' +
  1982. --inclusive filter
  1983. CASE
  1984. WHEN @filter <> '' THEN
  1985. CASE @filter_type
  1986. WHEN 'session' THEN
  1987. CASE
  1988. WHEN CONVERT(SMALLINT, @filter) <> 0 THEN
  1989. 'AND sp0.session_id = CONVERT(SMALLINT, @filter)
  1990. '
  1991. ELSE
  1992. ''
  1993. END
  1994. WHEN 'program' THEN
  1995. 'AND sp0.program_name LIKE @filter
  1996. '
  1997. WHEN 'login' THEN
  1998. 'AND sp0.login_name LIKE @filter
  1999. '
  2000. WHEN 'host' THEN
  2001. 'AND sp0.host_name LIKE @filter
  2002. '
  2003. WHEN 'database' THEN
  2004. 'AND DB_NAME(sp0.database_id) LIKE @filter
  2005. '
  2006. ELSE
  2007. ''
  2008. END
  2009. ELSE
  2010. ''
  2011. END +
  2012. --exclusive filter
  2013. CASE
  2014. WHEN @not_filter <> '' THEN
  2015. CASE @not_filter_type
  2016. WHEN 'session' THEN
  2017. CASE
  2018. WHEN CONVERT(SMALLINT, @not_filter) <> 0 THEN
  2019. 'AND sp0.session_id <> CONVERT(SMALLINT, @not_filter)
  2020. '
  2021. ELSE
  2022. ''
  2023. END
  2024. WHEN 'program' THEN
  2025. 'AND sp0.program_name NOT LIKE @not_filter
  2026. '
  2027. WHEN 'login' THEN
  2028. 'AND sp0.login_name NOT LIKE @not_filter
  2029. '
  2030. WHEN 'host' THEN
  2031. 'AND sp0.host_name NOT LIKE @not_filter
  2032. '
  2033. WHEN 'database' THEN
  2034. 'AND DB_NAME(sp0.database_id) NOT LIKE @not_filter
  2035. '
  2036. ELSE
  2037. ''
  2038. END
  2039. ELSE
  2040. ''
  2041. END +
  2042. CASE @show_own_spid
  2043. WHEN 1 THEN
  2044. ''
  2045. ELSE
  2046. 'AND sp0.session_id <> @@spid
  2047. '
  2048. END +
  2049. CASE
  2050. WHEN @show_system_spids = 0 THEN
  2051. 'AND sp0.hostprocess > ''''
  2052. '
  2053. ELSE
  2054. ''
  2055. END +
  2056. CASE @show_sleeping_spids
  2057. WHEN 0 THEN
  2058. 'AND sp0.status <> ''sleeping''
  2059. '
  2060. WHEN 1 THEN
  2061. 'AND
  2062. (
  2063. sp0.status <> ''sleeping''
  2064. OR sp0.open_tran_count > 0
  2065. )
  2066. '
  2067. ELSE
  2068. ''
  2069. END +
  2070. ')
  2071. ) AS spx
  2072. ) AS spy
  2073. WHERE
  2074. spy.r = 1;
  2075. ' +
  2076. CASE @recursion
  2077. WHEN 1 THEN
  2078. 'IF @@ROWCOUNT > 0
  2079. BEGIN;
  2080. INSERT @blockers
  2081. (
  2082. session_id
  2083. )
  2084. SELECT TOP(@i)
  2085. blocked
  2086. FROM @sessions
  2087. WHERE
  2088. NULLIF(blocked, 0) IS NOT NULL
  2089. EXCEPT
  2090. SELECT TOP(@i)
  2091. session_id
  2092. FROM @sessions;
  2093. ' +
  2094.  
  2095. CASE
  2096. WHEN
  2097. (
  2098. @get_task_info > 0
  2099. OR @find_block_leaders = 1
  2100. ) THEN
  2101. 'IF @@ROWCOUNT > 0
  2102. BEGIN;
  2103. SET @blocker = 1;
  2104. GOTO BLOCKERS;
  2105. END;
  2106. '
  2107. ELSE
  2108. ''
  2109. END +
  2110. 'END;
  2111. '
  2112. ELSE
  2113. ''
  2114. END +
  2115. 'SELECT TOP(@i)
  2116. @recursion AS recursion,
  2117. x.session_id,
  2118. x.request_id,
  2119. DENSE_RANK() OVER
  2120. (
  2121. ORDER BY
  2122. x.session_id
  2123. ) AS session_number,
  2124. ' +
  2125. CASE
  2126. WHEN @output_column_list LIKE '%|[dd hh:mm:ss.mss|]%' ESCAPE '|' THEN
  2127. 'x.elapsed_time '
  2128. ELSE
  2129. '0 '
  2130. END +
  2131. 'AS elapsed_time,
  2132. ' +
  2133. CASE
  2134. WHEN
  2135. (
  2136. @output_column_list LIKE '%|[dd hh:mm:ss.mss (avg)|]%' ESCAPE '|' OR
  2137. @output_column_list LIKE '%|[avg_elapsed_time|]%' ESCAPE '|'
  2138. )
  2139. AND @recursion = 1
  2140. THEN
  2141. 'x.avg_elapsed_time / 1000 '
  2142. ELSE
  2143. 'NULL '
  2144. END +
  2145. 'AS avg_elapsed_time,
  2146. ' +
  2147. CASE
  2148. WHEN
  2149. @output_column_list LIKE '%|[physical_io|]%' ESCAPE '|'
  2150. OR @output_column_list LIKE '%|[physical_io_delta|]%' ESCAPE '|'
  2151. THEN
  2152. 'x.physical_io '
  2153. ELSE
  2154. 'NULL '
  2155. END +
  2156. 'AS physical_io,
  2157. ' +
  2158. CASE
  2159. WHEN
  2160. @output_column_list LIKE '%|[reads|]%' ESCAPE '|'
  2161. OR @output_column_list LIKE '%|[reads_delta|]%' ESCAPE '|'
  2162. THEN
  2163. 'x.reads '
  2164. ELSE
  2165. '0 '
  2166. END +
  2167. 'AS reads,
  2168. ' +
  2169. CASE
  2170. WHEN
  2171. @output_column_list LIKE '%|[physical_reads|]%' ESCAPE '|'
  2172. OR @output_column_list LIKE '%|[physical_reads_delta|]%' ESCAPE '|'
  2173. THEN
  2174. 'x.physical_reads '
  2175. ELSE
  2176. '0 '
  2177. END +
  2178. 'AS physical_reads,
  2179. ' +
  2180. CASE
  2181. WHEN
  2182. @output_column_list LIKE '%|[writes|]%' ESCAPE '|'
  2183. OR @output_column_list LIKE '%|[writes_delta|]%' ESCAPE '|'
  2184. THEN
  2185. 'x.writes '
  2186. ELSE
  2187. '0 '
  2188. END +
  2189. 'AS writes,
  2190. ' +
  2191. CASE
  2192. WHEN
  2193. @output_column_list LIKE '%|[tempdb_allocations|]%' ESCAPE '|'
  2194. OR @output_column_list LIKE '%|[tempdb_allocations_delta|]%' ESCAPE '|'
  2195. THEN
  2196. 'x.tempdb_allocations '
  2197. ELSE
  2198. '0 '
  2199. END +
  2200. 'AS tempdb_allocations,
  2201. ' +
  2202. CASE
  2203. WHEN
  2204. @output_column_list LIKE '%|[tempdb_current|]%' ESCAPE '|'
  2205. OR @output_column_list LIKE '%|[tempdb_current_delta|]%' ESCAPE '|'
  2206. THEN
  2207. 'x.tempdb_current '
  2208. ELSE
  2209. '0 '
  2210. END +
  2211. 'AS tempdb_current,
  2212. ' +
  2213. CASE
  2214. WHEN
  2215. @output_column_list LIKE '%|[CPU|]%' ESCAPE '|'
  2216. OR @output_column_list LIKE '%|[CPU_delta|]%' ESCAPE '|'
  2217. THEN
  2218. 'x.CPU '
  2219. ELSE
  2220. '0 '
  2221. END +
  2222. 'AS CPU,
  2223. ' +
  2224. CASE
  2225. WHEN
  2226. @output_column_list LIKE '%|[CPU_delta|]%' ESCAPE '|'
  2227. AND @get_task_info = 2
  2228. AND @sys_info = 1
  2229. THEN
  2230. 'x.thread_CPU_snapshot '
  2231. ELSE
  2232. '0 '
  2233. END +
  2234. 'AS thread_CPU_snapshot,
  2235. ' +
  2236. CASE
  2237. WHEN
  2238. @output_column_list LIKE '%|[context_switches|]%' ESCAPE '|'
  2239. OR @output_column_list LIKE '%|[context_switches_delta|]%' ESCAPE '|'
  2240. THEN
  2241. 'x.context_switches '
  2242. ELSE
  2243. 'NULL '
  2244. END +
  2245. 'AS context_switches,
  2246. ' +
  2247. CASE
  2248. WHEN
  2249. @output_column_list LIKE '%|[used_memory|]%' ESCAPE '|'
  2250. OR @output_column_list LIKE '%|[used_memory_delta|]%' ESCAPE '|'
  2251. THEN
  2252. 'x.used_memory '
  2253. ELSE
  2254. '0 '
  2255. END +
  2256. 'AS used_memory,
  2257. ' +
  2258. CASE
  2259. WHEN
  2260. @output_column_list LIKE '%|[tasks|]%' ESCAPE '|'
  2261. AND @recursion = 1
  2262. THEN
  2263. 'x.tasks '
  2264. ELSE
  2265. 'NULL '
  2266. END +
  2267. 'AS tasks,
  2268. ' +
  2269. CASE
  2270. WHEN
  2271. (
  2272. @output_column_list LIKE '%|[status|]%' ESCAPE '|'
  2273. OR @output_column_list LIKE '%|[sql_command|]%' ESCAPE '|'
  2274. )
  2275. AND @recursion = 1
  2276. THEN
  2277. 'x.status '
  2278. ELSE
  2279. ''''' '
  2280. END +
  2281. 'AS status,
  2282. ' +
  2283. CASE
  2284. WHEN
  2285. @output_column_list LIKE '%|[wait_info|]%' ESCAPE '|'
  2286. AND @recursion = 1
  2287. THEN
  2288. CASE @get_task_info
  2289. WHEN 2 THEN
  2290. 'COALESCE(x.task_wait_info, x.sys_wait_info) '
  2291. ELSE
  2292. 'x.sys_wait_info '
  2293. END
  2294. ELSE
  2295. 'NULL '
  2296. END +
  2297. 'AS wait_info,
  2298. ' +
  2299. CASE
  2300. WHEN
  2301. (
  2302. @output_column_list LIKE '%|[tran_start_time|]%' ESCAPE '|'
  2303. OR @output_column_list LIKE '%|[tran_log_writes|]%' ESCAPE '|'
  2304. )
  2305. AND @recursion = 1
  2306. THEN
  2307. 'x.transaction_id '
  2308. ELSE
  2309. 'NULL '
  2310. END +
  2311. 'AS transaction_id,
  2312. ' +
  2313. CASE
  2314. WHEN
  2315. @output_column_list LIKE '%|[open_tran_count|]%' ESCAPE '|'
  2316. AND @recursion = 1
  2317. THEN
  2318. 'x.open_tran_count '
  2319. ELSE
  2320. 'NULL '
  2321. END +
  2322. 'AS open_tran_count,
  2323. ' +
  2324. CASE
  2325. WHEN
  2326. @output_column_list LIKE '%|[sql_text|]%' ESCAPE '|'
  2327. AND @recursion = 1
  2328. THEN
  2329. 'x.sql_handle '
  2330. ELSE
  2331. 'NULL '
  2332. END +
  2333. 'AS sql_handle,
  2334. ' +
  2335. CASE
  2336. WHEN
  2337. (
  2338. @output_column_list LIKE '%|[sql_text|]%' ESCAPE '|'
  2339. OR @output_column_list LIKE '%|[query_plan|]%' ESCAPE '|'
  2340. )
  2341. AND @recursion = 1
  2342. THEN
  2343. 'x.statement_start_offset '
  2344. ELSE
  2345. 'NULL '
  2346. END +
  2347. 'AS statement_start_offset,
  2348. ' +
  2349. CASE
  2350. WHEN
  2351. (
  2352. @output_column_list LIKE '%|[sql_text|]%' ESCAPE '|'
  2353. OR @output_column_list LIKE '%|[query_plan|]%' ESCAPE '|'
  2354. )
  2355. AND @recursion = 1
  2356. THEN
  2357. 'x.statement_end_offset '
  2358. ELSE
  2359. 'NULL '
  2360. END +
  2361. 'AS statement_end_offset,
  2362. ' +
  2363. 'NULL AS sql_text,
  2364. ' +
  2365. CASE
  2366. WHEN
  2367. @output_column_list LIKE '%|[query_plan|]%' ESCAPE '|'
  2368. AND @recursion = 1
  2369. THEN
  2370. 'x.plan_handle '
  2371. ELSE
  2372. 'NULL '
  2373. END +
  2374. 'AS plan_handle,
  2375. ' +
  2376. CASE
  2377. WHEN
  2378. @output_column_list LIKE '%|[blocking_session_id|]%' ESCAPE '|'
  2379. AND @recursion = 1
  2380. THEN
  2381. 'NULLIF(x.blocking_session_id, 0) '
  2382. ELSE
  2383. 'NULL '
  2384. END +
  2385. 'AS blocking_session_id,
  2386. ' +
  2387. CASE
  2388. WHEN
  2389. @output_column_list LIKE '%|[percent_complete|]%' ESCAPE '|'
  2390. AND @recursion = 1
  2391. THEN
  2392. 'x.percent_complete '
  2393. ELSE
  2394. 'NULL '
  2395. END +
  2396. 'AS percent_complete,
  2397. ' +
  2398. CASE
  2399. WHEN
  2400. @output_column_list LIKE '%|[host_name|]%' ESCAPE '|'
  2401. AND @recursion = 1
  2402. THEN
  2403. 'x.host_name '
  2404. ELSE
  2405. ''''' '
  2406. END +
  2407. 'AS host_name,
  2408. ' +
  2409. CASE
  2410. WHEN
  2411. @output_column_list LIKE '%|[login_name|]%' ESCAPE '|'
  2412. AND @recursion = 1
  2413. THEN
  2414. 'x.login_name '
  2415. ELSE
  2416. ''''' '
  2417. END +
  2418. 'AS login_name,
  2419. ' +
  2420. CASE
  2421. WHEN
  2422. @output_column_list LIKE '%|[database_name|]%' ESCAPE '|'
  2423. AND @recursion = 1
  2424. THEN
  2425. 'DB_NAME(x.database_id) '
  2426. ELSE
  2427. 'NULL '
  2428. END +
  2429. 'AS database_name,
  2430. ' +
  2431. CASE
  2432. WHEN
  2433. @output_column_list LIKE '%|[program_name|]%' ESCAPE '|'
  2434. AND @recursion = 1
  2435. THEN
  2436. 'x.program_name '
  2437. ELSE
  2438. ''''' '
  2439. END +
  2440. 'AS program_name,
  2441. ' +
  2442. CASE
  2443. WHEN
  2444. @output_column_list LIKE '%|[additional_info|]%' ESCAPE '|'
  2445. AND @recursion = 1
  2446. THEN
  2447. '(
  2448. SELECT TOP(@i)
  2449. x.text_size,
  2450. x.language,
  2451. x.date_format,
  2452. x.date_first,
  2453. CASE x.quoted_identifier
  2454. WHEN 0 THEN ''OFF''
  2455. WHEN 1 THEN ''ON''
  2456. END AS quoted_identifier,
  2457. CASE x.arithabort
  2458. WHEN 0 THEN ''OFF''
  2459. WHEN 1 THEN ''ON''
  2460. END AS arithabort,
  2461. CASE x.ansi_null_dflt_on
  2462. WHEN 0 THEN ''OFF''
  2463. WHEN 1 THEN ''ON''
  2464. END AS ansi_null_dflt_on,
  2465. CASE x.ansi_defaults
  2466. WHEN 0 THEN ''OFF''
  2467. WHEN 1 THEN ''ON''
  2468. END AS ansi_defaults,
  2469. CASE x.ansi_warnings
  2470. WHEN 0 THEN ''OFF''
  2471. WHEN 1 THEN ''ON''
  2472. END AS ansi_warnings,
  2473. CASE x.ansi_padding
  2474. WHEN 0 THEN ''OFF''
  2475. WHEN 1 THEN ''ON''
  2476. END AS ansi_padding,
  2477. CASE ansi_nulls
  2478. WHEN 0 THEN ''OFF''
  2479. WHEN 1 THEN ''ON''
  2480. END AS ansi_nulls,
  2481. CASE x.concat_null_yields_null
  2482. WHEN 0 THEN ''OFF''
  2483. WHEN 1 THEN ''ON''
  2484. END AS concat_null_yields_null,
  2485. CASE x.transaction_isolation_level
  2486. WHEN 0 THEN ''Unspecified''
  2487. WHEN 1 THEN ''ReadUncomitted''
  2488. WHEN 2 THEN ''ReadCommitted''
  2489. WHEN 3 THEN ''Repeatable''
  2490. WHEN 4 THEN ''Serializable''
  2491. WHEN 5 THEN ''Snapshot''
  2492. END AS transaction_isolation_level,
  2493. x.lock_timeout,
  2494. x.deadlock_priority,
  2495. x.row_count,
  2496. x.command_type,
  2497. ' +
  2498. CASE
  2499. WHEN OBJECT_ID('master.dbo.fn_varbintohexstr') IS NOT NULL THEN
  2500. 'master.dbo.fn_varbintohexstr(x.sql_handle) AS sql_handle,
  2501. master.dbo.fn_varbintohexstr(x.plan_handle) AS plan_handle,'
  2502. ELSE
  2503. 'CONVERT(VARCHAR(256), x.sql_handle, 1) AS sql_handle,
  2504. CONVERT(VARCHAR(256), x.plan_handle, 1) AS plan_handle,'
  2505. END +
  2506. '
  2507. x.statement_start_offset,
  2508. x.statement_end_offset,
  2509. ' +
  2510. CASE
  2511. WHEN @output_column_list LIKE '%|[program_name|]%' ESCAPE '|' THEN
  2512. '(
  2513. SELECT TOP(1)
  2514. CONVERT(uniqueidentifier, CONVERT(XML, '''').value(''xs:hexBinary( substring(sql:column("agent_info.job_id_string"), 0) )'', ''binary(16)'')) AS job_id,
  2515. agent_info.step_id,
  2516. (
  2517. SELECT TOP(1)
  2518. NULL
  2519. FOR XML
  2520. PATH(''job_name''),
  2521. TYPE
  2522. ),
  2523. (
  2524. SELECT TOP(1)
  2525. NULL
  2526. FOR XML
  2527. PATH(''step_name''),
  2528. TYPE
  2529. )
  2530. FROM
  2531. (
  2532. SELECT TOP(1)
  2533. SUBSTRING(x.program_name, CHARINDEX(''0x'', x.program_name) + 2, 32) AS job_id_string,
  2534. SUBSTRING(x.program_name, CHARINDEX('': Step '', x.program_name) + 7, CHARINDEX('')'', x.program_name, CHARINDEX('': Step '', x.program_name)) - (CHARINDEX('': Step '', x.program_name) + 7)) AS step_id
  2535. WHERE
  2536. x.program_name LIKE N''SQLAgent - TSQL JobStep (Job 0x%''
  2537. ) AS agent_info
  2538. FOR XML
  2539. PATH(''agent_job_info''),
  2540. TYPE
  2541. ),
  2542. '
  2543. ELSE ''
  2544. END +
  2545. CASE
  2546. WHEN @get_task_info = 2 THEN
  2547. 'CONVERT(XML, x.block_info) AS block_info,
  2548. '
  2549. ELSE
  2550. ''
  2551. END + '
  2552. x.host_process_id,
  2553. x.group_id
  2554. FOR XML
  2555. PATH(''additional_info''),
  2556. TYPE
  2557. ) '
  2558. ELSE
  2559. 'NULL '
  2560. END +
  2561. 'AS additional_info,
  2562. x.start_time,
  2563. ' +
  2564. CASE
  2565. WHEN
  2566. @output_column_list LIKE '%|[login_time|]%' ESCAPE '|'
  2567. AND @recursion = 1
  2568. THEN
  2569. 'x.login_time '
  2570. ELSE
  2571. 'NULL '
  2572. END +
  2573. 'AS login_time,
  2574. x.last_request_start_time
  2575. FROM
  2576. (
  2577. SELECT TOP(@i)
  2578. y.*,
  2579. CASE
  2580. WHEN DATEDIFF(hour, y.start_time, GETDATE()) > 576 THEN
  2581. DATEDIFF(second, GETDATE(), y.start_time)
  2582. ELSE DATEDIFF(ms, y.start_time, GETDATE())
  2583. END AS elapsed_time,
  2584. COALESCE(tempdb_info.tempdb_allocations, 0) AS tempdb_allocations,
  2585. COALESCE
  2586. (
  2587. CASE
  2588. WHEN tempdb_info.tempdb_current < 0 THEN 0
  2589. ELSE tempdb_info.tempdb_current
  2590. END,
  2591. 0
  2592. ) AS tempdb_current,
  2593. ' +
  2594. CASE
  2595. WHEN
  2596. (
  2597. @get_task_info <> 0
  2598. OR @find_block_leaders = 1
  2599. ) THEN
  2600. 'N''('' + CONVERT(NVARCHAR, y.wait_duration_ms) + N''ms)'' +
  2601. y.wait_type +
  2602. CASE
  2603. WHEN y.wait_type LIKE N''PAGE%LATCH_%'' THEN
  2604. N'':'' +
  2605. COALESCE(DB_NAME(CONVERT(INT, LEFT(y.resource_description, CHARINDEX(N'':'', y.resource_description) - 1))), N''(null)'') +
  2606. N'':'' +
  2607. SUBSTRING(y.resource_description, CHARINDEX(N'':'', y.resource_description) + 1, LEN(y.resource_description) - CHARINDEX(N'':'', REVERSE(y.resource_description)) - CHARINDEX(N'':'', y.resource_description)) +
  2608. N''('' +
  2609. CASE
  2610. WHEN
  2611. CONVERT(INT, RIGHT(y.resource_description, CHARINDEX(N'':'', REVERSE(y.resource_description)) - 1)) = 1 OR
  2612. CONVERT(INT, RIGHT(y.resource_description, CHARINDEX(N'':'', REVERSE(y.resource_description)) - 1)) % 8088 = 0
  2613. THEN
  2614. N''PFS''
  2615. WHEN
  2616. CONVERT(INT, RIGHT(y.resource_description, CHARINDEX(N'':'', REVERSE(y.resource_description)) - 1)) = 2 OR
  2617. CONVERT(INT, RIGHT(y.resource_description, CHARINDEX(N'':'', REVERSE(y.resource_description)) - 1)) % 511232 = 0
  2618. THEN
  2619. N''GAM''
  2620. WHEN
  2621. CONVERT(INT, RIGHT(y.resource_description, CHARINDEX(N'':'', REVERSE(y.resource_description)) - 1)) = 3 OR
  2622. (CONVERT(INT, RIGHT(y.resource_description, CHARINDEX(N'':'', REVERSE(y.resource_description)) - 1)) - 1) % 511232 = 0
  2623. THEN
  2624. N''SGAM''
  2625. WHEN
  2626. CONVERT(INT, RIGHT(y.resource_description, CHARINDEX(N'':'', REVERSE(y.resource_description)) - 1)) = 6 OR
  2627. (CONVERT(INT, RIGHT(y.resource_description, CHARINDEX(N'':'', REVERSE(y.resource_description)) - 1)) - 6) % 511232 = 0
  2628. THEN
  2629. N''DCM''
  2630. WHEN
  2631. CONVERT(INT, RIGHT(y.resource_description, CHARINDEX(N'':'', REVERSE(y.resource_description)) - 1)) = 7 OR
  2632. (CONVERT(INT, RIGHT(y.resource_description, CHARINDEX(N'':'', REVERSE(y.resource_description)) - 1)) - 7) % 511232 = 0
  2633. THEN
  2634. N''BCM''
  2635. ELSE
  2636. N''*''
  2637. END +
  2638. N'')''
  2639. WHEN y.wait_type = N''CXPACKET'' THEN
  2640. N'':'' + SUBSTRING(y.resource_description, CHARINDEX(N''nodeId'', y.resource_description) + 7, 4)
  2641. WHEN y.wait_type LIKE N''LATCH[_]%'' THEN
  2642. N'' ['' + LEFT(y.resource_description, COALESCE(NULLIF(CHARINDEX(N'' '', y.resource_description), 0), LEN(y.resource_description) + 1) - 1) + N'']''
  2643. WHEN
  2644. y.wait_type = N''OLEDB''
  2645. AND y.resource_description LIKE N''%(SPID=%)'' THEN
  2646. N''['' + LEFT(y.resource_description, CHARINDEX(N''(SPID='', y.resource_description) - 2) +
  2647. N'':'' + SUBSTRING(y.resource_description, CHARINDEX(N''(SPID='', y.resource_description) + 6, CHARINDEX(N'')'', y.resource_description, (CHARINDEX(N''(SPID='', y.resource_description) + 6)) - (CHARINDEX(N''(SPID='', y.resource_description) + 6)) + '']''
  2648. ELSE
  2649. N''''
  2650. END COLLATE Latin1_General_Bin2 AS sys_wait_info,
  2651. '
  2652. ELSE
  2653. ''
  2654. END +
  2655. CASE
  2656. WHEN @get_task_info = 2 THEN
  2657. 'tasks.physical_io,
  2658. tasks.context_switches,
  2659. tasks.tasks,
  2660. tasks.block_info,
  2661. tasks.wait_info AS task_wait_info,
  2662. tasks.thread_CPU_snapshot,
  2663. '
  2664. ELSE
  2665. ''
  2666. END +
  2667. CASE
  2668. WHEN NOT (@get_avg_time = 1 AND @recursion = 1) THEN
  2669. 'CONVERT(INT, NULL) '
  2670. ELSE
  2671. 'qs.total_elapsed_time / qs.execution_count '
  2672. END +
  2673. 'AS avg_elapsed_time
  2674. FROM
  2675. (
  2676. SELECT TOP(@i)
  2677. sp.session_id,
  2678. sp.request_id,
  2679. COALESCE(r.logical_reads, s.logical_reads) AS reads,
  2680. COALESCE(r.reads, s.reads) AS physical_reads,
  2681. COALESCE(r.writes, s.writes) AS writes,
  2682. COALESCE(r.CPU_time, s.CPU_time) AS CPU,
  2683. sp.memory_usage + COALESCE(r.granted_query_memory, 0) AS used_memory,
  2684. LOWER(sp.status) AS status,
  2685. COALESCE(r.sql_handle, sp.sql_handle) AS sql_handle,
  2686. COALESCE(r.statement_start_offset, sp.statement_start_offset) AS statement_start_offset,
  2687. COALESCE(r.statement_end_offset, sp.statement_end_offset) AS statement_end_offset,
  2688. ' +
  2689. CASE
  2690. WHEN
  2691. (
  2692. @get_task_info <> 0
  2693. OR @find_block_leaders = 1
  2694. ) THEN
  2695. 'sp.wait_type COLLATE Latin1_General_Bin2 AS wait_type,
  2696. sp.wait_resource COLLATE Latin1_General_Bin2 AS resource_description,
  2697. sp.wait_time AS wait_duration_ms,
  2698. '
  2699. ELSE
  2700. ''
  2701. END +
  2702. 'NULLIF(sp.blocked, 0) AS blocking_session_id,
  2703. r.plan_handle,
  2704. NULLIF(r.percent_complete, 0) AS percent_complete,
  2705. sp.host_name,
  2706. sp.login_name,
  2707. sp.program_name,
  2708. s.host_process_id,
  2709. COALESCE(r.text_size, s.text_size) AS text_size,
  2710. COALESCE(r.language, s.language) AS language,
  2711. COALESCE(r.date_format, s.date_format) AS date_format,
  2712. COALESCE(r.date_first, s.date_first) AS date_first,
  2713. COALESCE(r.quoted_identifier, s.quoted_identifier) AS quoted_identifier,
  2714. COALESCE(r.arithabort, s.arithabort) AS arithabort,
  2715. COALESCE(r.ansi_null_dflt_on, s.ansi_null_dflt_on) AS ansi_null_dflt_on,
  2716. COALESCE(r.ansi_defaults, s.ansi_defaults) AS ansi_defaults,
  2717. COALESCE(r.ansi_warnings, s.ansi_warnings) AS ansi_warnings,
  2718. COALESCE(r.ansi_padding, s.ansi_padding) AS ansi_padding,
  2719. COALESCE(r.ansi_nulls, s.ansi_nulls) AS ansi_nulls,
  2720. COALESCE(r.concat_null_yields_null, s.concat_null_yields_null) AS concat_null_yields_null,
  2721. COALESCE(r.transaction_isolation_level, s.transaction_isolation_level) AS transaction_isolation_level,
  2722. COALESCE(r.lock_timeout, s.lock_timeout) AS lock_timeout,
  2723. COALESCE(r.deadlock_priority, s.deadlock_priority) AS deadlock_priority,
  2724. COALESCE(r.row_count, s.row_count) AS row_count,
  2725. COALESCE(r.command, sp.cmd) AS command_type,
  2726. COALESCE
  2727. (
  2728. CASE
  2729. WHEN
  2730. (
  2731. s.is_user_process = 0
  2732. AND r.total_elapsed_time >= 0
  2733. ) THEN
  2734. DATEADD
  2735. (
  2736. ms,
  2737. 1000 * (DATEPART(ms, DATEADD(second, -(r.total_elapsed_time / 1000), GETDATE())) / 500) - DATEPART(ms, DATEADD(second, -(r.total_elapsed_time / 1000), GETDATE())),
  2738. DATEADD(second, -(r.total_elapsed_time / 1000), GETDATE())
  2739. )
  2740. END,
  2741. NULLIF(COALESCE(r.start_time, sp.last_request_end_time), CONVERT(DATETIME, ''19000101'', 112)),
  2742. sp.login_time
  2743. ) AS start_time,
  2744. sp.login_time,
  2745. CASE
  2746. WHEN s.is_user_process = 1 THEN
  2747. s.last_request_start_time
  2748. ELSE
  2749. COALESCE
  2750. (
  2751. DATEADD
  2752. (
  2753. ms,
  2754. 1000 * (DATEPART(ms, DATEADD(second, -(r.total_elapsed_time / 1000), GETDATE())) / 500) - DATEPART(ms, DATEADD(second, -(r.total_elapsed_time / 1000), GETDATE())),
  2755. DATEADD(second, -(r.total_elapsed_time / 1000), GETDATE())
  2756. ),
  2757. s.last_request_start_time
  2758. )
  2759. END AS last_request_start_time,
  2760. r.transaction_id,
  2761. sp.database_id,
  2762. sp.open_tran_count,
  2763. ' +
  2764. CASE
  2765. WHEN EXISTS
  2766. (
  2767. SELECT
  2768. *
  2769. FROM sys.all_columns AS ac
  2770. WHERE
  2771. ac.object_id = OBJECT_ID('sys.dm_exec_sessions')
  2772. AND ac.name = 'group_id'
  2773. )
  2774. THEN 's.group_id'
  2775. ELSE 'CONVERT(INT, NULL) AS group_id'
  2776. END + '
  2777. FROM @sessions AS sp
  2778. LEFT OUTER LOOP JOIN sys.dm_exec_sessions AS s ON
  2779. s.session_id = sp.session_id
  2780. AND s.login_time = sp.login_time
  2781. LEFT OUTER LOOP JOIN sys.dm_exec_requests AS r ON
  2782. sp.status <> ''sleeping''
  2783. AND r.session_id = sp.session_id
  2784. AND r.request_id = sp.request_id
  2785. AND
  2786. (
  2787. (
  2788. s.is_user_process = 0
  2789. AND sp.is_user_process = 0
  2790. )
  2791. OR
  2792. (
  2793. r.start_time = s.last_request_start_time
  2794. AND s.last_request_end_time <= sp.last_request_end_time
  2795. )
  2796. )
  2797. ) AS y
  2798. ' +
  2799. CASE
  2800. WHEN @get_task_info = 2 THEN
  2801. CONVERT(VARCHAR(MAX), '') +
  2802. 'LEFT OUTER HASH JOIN
  2803. (
  2804. SELECT TOP(@i)
  2805. task_nodes.task_node.value(''(session_id/text())[1]'', ''SMALLINT'') AS session_id,
  2806. task_nodes.task_node.value(''(request_id/text())[1]'', ''INT'') AS request_id,
  2807. task_nodes.task_node.value(''(physical_io/text())[1]'', ''BIGINT'') AS physical_io,
  2808. task_nodes.task_node.value(''(context_switches/text())[1]'', ''BIGINT'') AS context_switches,
  2809. task_nodes.task_node.value(''(tasks/text())[1]'', ''INT'') AS tasks,
  2810. task_nodes.task_node.value(''(block_info/text())[1]'', ''NVARCHAR(4000)'') AS block_info,
  2811. task_nodes.task_node.value(''(waits/text())[1]'', ''NVARCHAR(4000)'') AS wait_info,
  2812. task_nodes.task_node.value(''(thread_CPU_snapshot/text())[1]'', ''BIGINT'') AS thread_CPU_snapshot
  2813. FROM
  2814. (
  2815. SELECT TOP(@i)
  2816. CONVERT
  2817. (
  2818. XML,
  2819. REPLACE
  2820. (
  2821. CONVERT(NVARCHAR(MAX), tasks_raw.task_xml_raw) COLLATE Latin1_General_Bin2,
  2822. N''</waits></tasks><tasks><waits>'',
  2823. N'', ''
  2824. )
  2825. ) AS task_xml
  2826. FROM
  2827. (
  2828. SELECT TOP(@i)
  2829. CASE waits.r
  2830. WHEN 1 THEN
  2831. waits.session_id
  2832. ELSE
  2833. NULL
  2834. END AS [session_id],
  2835. CASE waits.r
  2836. WHEN 1 THEN
  2837. waits.request_id
  2838. ELSE
  2839. NULL
  2840. END AS [request_id],
  2841. CASE waits.r
  2842. WHEN 1 THEN
  2843. waits.physical_io
  2844. ELSE
  2845. NULL
  2846. END AS [physical_io],
  2847. CASE waits.r
  2848. WHEN 1 THEN
  2849. waits.context_switches
  2850. ELSE
  2851. NULL
  2852. END AS [context_switches],
  2853. CASE waits.r
  2854. WHEN 1 THEN
  2855. waits.thread_CPU_snapshot
  2856. ELSE
  2857. NULL
  2858. END AS [thread_CPU_snapshot],
  2859. CASE waits.r
  2860. WHEN 1 THEN
  2861. waits.tasks
  2862. ELSE
  2863. NULL
  2864. END AS [tasks],
  2865. CASE waits.r
  2866. WHEN 1 THEN
  2867. waits.block_info
  2868. ELSE
  2869. NULL
  2870. END AS [block_info],
  2871. REPLACE
  2872. (
  2873. REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
  2874. REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
  2875. REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
  2876. CONVERT
  2877. (
  2878. NVARCHAR(MAX),
  2879. N''('' +
  2880. CONVERT(NVARCHAR, num_waits) + N''x: '' +
  2881. CASE num_waits
  2882. WHEN 1 THEN
  2883. CONVERT(NVARCHAR, min_wait_time) + N''ms''
  2884. WHEN 2 THEN
  2885. CASE
  2886. WHEN min_wait_time <> max_wait_time THEN
  2887. CONVERT(NVARCHAR, min_wait_time) + N''/'' + CONVERT(NVARCHAR, max_wait_time) + N''ms''
  2888. ELSE
  2889. CONVERT(NVARCHAR, max_wait_time) + N''ms''
  2890. END
  2891. ELSE
  2892. CASE
  2893. WHEN min_wait_time <> max_wait_time THEN
  2894. CONVERT(NVARCHAR, min_wait_time) + N''/'' + CONVERT(NVARCHAR, avg_wait_time) + N''/'' + CONVERT(NVARCHAR, max_wait_time) + N''ms''
  2895. ELSE
  2896. CONVERT(NVARCHAR, max_wait_time) + N''ms''
  2897. END
  2898. END +
  2899. N'')'' + wait_type COLLATE Latin1_General_Bin2
  2900. ),
  2901. NCHAR(31),N''?''),NCHAR(30),N''?''),NCHAR(29),N''?''),NCHAR(28),N''?''),NCHAR(27),N''?''),NCHAR(26),N''?''),NCHAR(25),N''?''),NCHAR(24),N''?''),NCHAR(23),N''?''),NCHAR(22),N''?''),
  2902. NCHAR(21),N''?''),NCHAR(20),N''?''),NCHAR(19),N''?''),NCHAR(18),N''?''),NCHAR(17),N''?''),NCHAR(16),N''?''),NCHAR(15),N''?''),NCHAR(14),N''?''),NCHAR(12),N''?''),
  2903. NCHAR(11),N''?''),NCHAR(8),N''?''),NCHAR(7),N''?''),NCHAR(6),N''?''),NCHAR(5),N''?''),NCHAR(4),N''?''),NCHAR(3),N''?''),NCHAR(2),N''?''),NCHAR(1),N''?''),
  2904. NCHAR(0),
  2905. N''''
  2906. ) AS [waits]
  2907. FROM
  2908. (
  2909. SELECT TOP(@i)
  2910. w1.*,
  2911. ROW_NUMBER() OVER
  2912. (
  2913. PARTITION BY
  2914. w1.session_id,
  2915. w1.request_id
  2916. ORDER BY
  2917. w1.block_info DESC,
  2918. w1.num_waits DESC,
  2919. w1.wait_type
  2920. ) AS r
  2921. FROM
  2922. (
  2923. SELECT TOP(@i)
  2924. task_info.session_id,
  2925. task_info.request_id,
  2926. task_info.physical_io,
  2927. task_info.context_switches,
  2928. task_info.thread_CPU_snapshot,
  2929. task_info.num_tasks AS tasks,
  2930. CASE
  2931. WHEN task_info.runnable_time IS NOT NULL THEN
  2932. ''RUNNABLE''
  2933. ELSE
  2934. wt2.wait_type
  2935. END AS wait_type,
  2936. NULLIF(COUNT(COALESCE(task_info.runnable_time, wt2.waiting_task_address)), 0) AS num_waits,
  2937. MIN(COALESCE(task_info.runnable_time, wt2.wait_duration_ms)) AS min_wait_time,
  2938. AVG(COALESCE(task_info.runnable_time, wt2.wait_duration_ms)) AS avg_wait_time,
  2939. MAX(COALESCE(task_info.runnable_time, wt2.wait_duration_ms)) AS max_wait_time,
  2940. MAX(wt2.block_info) AS block_info
  2941. FROM
  2942. (
  2943. SELECT TOP(@i)
  2944. t.session_id,
  2945. t.request_id,
  2946. SUM(CONVERT(BIGINT, t.pending_io_count)) OVER (PARTITION BY t.session_id, t.request_id) AS physical_io,
  2947. SUM(CONVERT(BIGINT, t.context_switches_count)) OVER (PARTITION BY t.session_id, t.request_id) AS context_switches,
  2948. ' +
  2949. CASE
  2950. WHEN
  2951. @output_column_list LIKE '%|[CPU_delta|]%' ESCAPE '|'
  2952. AND @sys_info = 1
  2953. THEN
  2954. 'SUM(tr.usermode_time + tr.kernel_time) OVER (PARTITION BY t.session_id, t.request_id) '
  2955. ELSE
  2956. 'CONVERT(BIGINT, NULL) '
  2957. END +
  2958. ' AS thread_CPU_snapshot,
  2959. COUNT(*) OVER (PARTITION BY t.session_id, t.request_id) AS num_tasks,
  2960. t.task_address,
  2961. t.task_state,
  2962. CASE
  2963. WHEN
  2964. t.task_state = ''RUNNABLE''
  2965. AND w.runnable_time > 0 THEN
  2966. w.runnable_time
  2967. ELSE
  2968. NULL
  2969. END AS runnable_time
  2970. FROM sys.dm_os_tasks AS t
  2971. CROSS APPLY
  2972. (
  2973. SELECT TOP(1)
  2974. sp2.session_id
  2975. FROM @sessions AS sp2
  2976. WHERE
  2977. sp2.session_id = t.session_id
  2978. AND sp2.request_id = t.request_id
  2979. AND sp2.status <> ''sleeping''
  2980. ) AS sp20
  2981. LEFT OUTER HASH JOIN
  2982. (
  2983. ' +
  2984. CASE
  2985. WHEN @sys_info = 1 THEN
  2986. 'SELECT TOP(@i)
  2987. (
  2988. SELECT TOP(@i)
  2989. ms_ticks
  2990. FROM sys.dm_os_sys_info
  2991. ) -
  2992. w0.wait_resumed_ms_ticks AS runnable_time,
  2993. w0.worker_address,
  2994. w0.thread_address,
  2995. w0.task_bound_ms_ticks
  2996. FROM sys.dm_os_workers AS w0
  2997. WHERE
  2998. w0.state = ''RUNNABLE''
  2999. OR @first_collection_ms_ticks >= w0.task_bound_ms_ticks'
  3000. ELSE
  3001. 'SELECT
  3002. CONVERT(BIGINT, NULL) AS runnable_time,
  3003. CONVERT(VARBINARY(8), NULL) AS worker_address,
  3004. CONVERT(VARBINARY(8), NULL) AS thread_address,
  3005. CONVERT(BIGINT, NULL) AS task_bound_ms_ticks
  3006. WHERE
  3007. 1 = 0'
  3008. END +
  3009. '
  3010. ) AS w ON
  3011. w.worker_address = t.worker_address
  3012. ' +
  3013. CASE
  3014. WHEN
  3015. @output_column_list LIKE '%|[CPU_delta|]%' ESCAPE '|'
  3016. AND @sys_info = 1
  3017. THEN
  3018. 'LEFT OUTER HASH JOIN sys.dm_os_threads AS tr ON
  3019. tr.thread_address = w.thread_address
  3020. AND @first_collection_ms_ticks >= w.task_bound_ms_ticks
  3021. '
  3022. ELSE
  3023. ''
  3024. END +
  3025. ') AS task_info
  3026. LEFT OUTER HASH JOIN
  3027. (
  3028. SELECT TOP(@i)
  3029. wt1.wait_type,
  3030. wt1.waiting_task_address,
  3031. MAX(wt1.wait_duration_ms) AS wait_duration_ms,
  3032. MAX(wt1.block_info) AS block_info
  3033. FROM
  3034. (
  3035. SELECT DISTINCT TOP(@i)
  3036. wt.wait_type +
  3037. CASE
  3038. WHEN wt.wait_type LIKE N''PAGE%LATCH_%'' THEN
  3039. '':'' +
  3040. COALESCE(DB_NAME(CONVERT(INT, LEFT(wt.resource_description, CHARINDEX(N'':'', wt.resource_description) - 1))), N''(null)'') +
  3041. N'':'' +
  3042. SUBSTRING(wt.resource_description, CHARINDEX(N'':'', wt.resource_description) + 1, LEN(wt.resource_description) - CHARINDEX(N'':'', REVERSE(wt.resource_description)) - CHARINDEX(N'':'', wt.resource_description)) +
  3043. N''('' +
  3044. CASE
  3045. WHEN
  3046. CONVERT(INT, RIGHT(wt.resource_description, CHARINDEX(N'':'', REVERSE(wt.resource_description)) - 1)) = 1 OR
  3047. CONVERT(INT, RIGHT(wt.resource_description, CHARINDEX(N'':'', REVERSE(wt.resource_description)) - 1)) % 8088 = 0
  3048. THEN
  3049. N''PFS''
  3050. WHEN
  3051. CONVERT(INT, RIGHT(wt.resource_description, CHARINDEX(N'':'', REVERSE(wt.resource_description)) - 1)) = 2 OR
  3052. CONVERT(INT, RIGHT(wt.resource_description, CHARINDEX(N'':'', REVERSE(wt.resource_description)) - 1)) % 511232 = 0
  3053. THEN
  3054. N''GAM''
  3055. WHEN
  3056. CONVERT(INT, RIGHT(wt.resource_description, CHARINDEX(N'':'', REVERSE(wt.resource_description)) - 1)) = 3 OR
  3057. (CONVERT(INT, RIGHT(wt.resource_description, CHARINDEX(N'':'', REVERSE(wt.resource_description)) - 1)) - 1) % 511232 = 0
  3058. THEN
  3059. N''SGAM''
  3060. WHEN
  3061. CONVERT(INT, RIGHT(wt.resource_description, CHARINDEX(N'':'', REVERSE(wt.resource_description)) - 1)) = 6 OR
  3062. (CONVERT(INT, RIGHT(wt.resource_description, CHARINDEX(N'':'', REVERSE(wt.resource_description)) - 1)) - 6) % 511232 = 0
  3063. THEN
  3064. N''DCM''
  3065. WHEN
  3066. CONVERT(INT, RIGHT(wt.resource_description, CHARINDEX(N'':'', REVERSE(wt.resource_description)) - 1)) = 7 OR
  3067. (CONVERT(INT, RIGHT(wt.resource_description, CHARINDEX(N'':'', REVERSE(wt.resource_description)) - 1)) - 7) % 511232 = 0
  3068. THEN
  3069. N''BCM''
  3070. ELSE
  3071. N''*''
  3072. END +
  3073. N'')''
  3074. WHEN wt.wait_type = N''CXPACKET'' THEN
  3075. N'':'' + SUBSTRING(wt.resource_description, CHARINDEX(N''nodeId'', wt.resource_description) + 7, 4)
  3076. WHEN wt.wait_type LIKE N''LATCH[_]%'' THEN
  3077. N'' ['' + LEFT(wt.resource_description, COALESCE(NULLIF(CHARINDEX(N'' '', wt.resource_description), 0), LEN(wt.resource_description) + 1) - 1) + N'']''
  3078. ELSE
  3079. N''''
  3080. END COLLATE Latin1_General_Bin2 AS wait_type,
  3081. CASE
  3082. WHEN
  3083. (
  3084. wt.blocking_session_id IS NOT NULL
  3085. AND wt.wait_type LIKE N''LCK[_]%''
  3086. ) THEN
  3087. (
  3088. SELECT TOP(@i)
  3089. x.lock_type,
  3090. REPLACE
  3091. (
  3092. REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
  3093. REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
  3094. REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
  3095. DB_NAME
  3096. (
  3097. CONVERT
  3098. (
  3099. INT,
  3100. SUBSTRING(wt.resource_description, NULLIF(CHARINDEX(N''dbid='', wt.resource_description), 0) + 5, COALESCE(NULLIF(CHARINDEX(N'' '', wt.resource_description, CHARINDEX(N''dbid='', wt.resource_description) + 5), 0), LEN(wt.resource_description) + 1) - CHARINDEX(N''dbid='', wt.resource_description) - 5)
  3101. )
  3102. ),
  3103. NCHAR(31),N''?''),NCHAR(30),N''?''),NCHAR(29),N''?''),NCHAR(28),N''?''),NCHAR(27),N''?''),NCHAR(26),N''?''),NCHAR(25),N''?''),NCHAR(24),N''?''),NCHAR(23),N''?''),NCHAR(22),N''?''),
  3104. NCHAR(21),N''?''),NCHAR(20),N''?''),NCHAR(19),N''?''),NCHAR(18),N''?''),NCHAR(17),N''?''),NCHAR(16),N''?''),NCHAR(15),N''?''),NCHAR(14),N''?''),NCHAR(12),N''?''),
  3105. NCHAR(11),N''?''),NCHAR(8),N''?''),NCHAR(7),N''?''),NCHAR(6),N''?''),NCHAR(5),N''?''),NCHAR(4),N''?''),NCHAR(3),N''?''),NCHAR(2),N''?''),NCHAR(1),N''?''),
  3106. NCHAR(0),
  3107. N''''
  3108. ) AS database_name,
  3109. CASE x.lock_type
  3110. WHEN N''objectlock'' THEN
  3111. SUBSTRING(wt.resource_description, NULLIF(CHARINDEX(N''objid='', wt.resource_description), 0) + 6, COALESCE(NULLIF(CHARINDEX(N'' '', wt.resource_description, CHARINDEX(N''objid='', wt.resource_description) + 6), 0), LEN(wt.resource_description) + 1) - CHARINDEX(N''objid='', wt.resource_description) - 6)
  3112. ELSE
  3113. NULL
  3114. END AS object_id,
  3115. CASE x.lock_type
  3116. WHEN N''filelock'' THEN
  3117. SUBSTRING(wt.resource_description, NULLIF(CHARINDEX(N''fileid='', wt.resource_description), 0) + 7, COALESCE(NULLIF(CHARINDEX(N'' '', wt.resource_description, CHARINDEX(N''fileid='', wt.resource_description) + 7), 0), LEN(wt.resource_description) + 1) - CHARINDEX(N''fileid='', wt.resource_description) - 7)
  3118. ELSE
  3119. NULL
  3120. END AS file_id,
  3121. CASE
  3122. WHEN x.lock_type in (N''pagelock'', N''extentlock'', N''ridlock'') THEN
  3123. SUBSTRING(wt.resource_description, NULLIF(CHARINDEX(N''associatedObjectId='', wt.resource_description), 0) + 19, COALESCE(NULLIF(CHARINDEX(N'' '', wt.resource_description, CHARINDEX(N''associatedObjectId='', wt.resource_description) + 19), 0), LEN(wt.resource_description) + 1) - CHARINDEX(N''associatedObjectId='', wt.resource_description) - 19)
  3124. WHEN x.lock_type in (N''keylock'', N''hobtlock'', N''allocunitlock'') THEN
  3125. SUBSTRING(wt.resource_description, NULLIF(CHARINDEX(N''hobtid='', wt.resource_description), 0) + 7, COALESCE(NULLIF(CHARINDEX(N'' '', wt.resource_description, CHARINDEX(N''hobtid='', wt.resource_description) + 7), 0), LEN(wt.resource_description) + 1) - CHARINDEX(N''hobtid='', wt.resource_description) - 7)
  3126. ELSE
  3127. NULL
  3128. END AS hobt_id,
  3129. CASE x.lock_type
  3130. WHEN N''applicationlock'' THEN
  3131. SUBSTRING(wt.resource_description, NULLIF(CHARINDEX(N''hash='', wt.resource_description), 0) + 5, COALESCE(NULLIF(CHARINDEX(N'' '', wt.resource_description, CHARINDEX(N''hash='', wt.resource_description) + 5), 0), LEN(wt.resource_description) + 1) - CHARINDEX(N''hash='', wt.resource_description) - 5)
  3132. ELSE
  3133. NULL
  3134. END AS applock_hash,
  3135. CASE x.lock_type
  3136. WHEN N''metadatalock'' THEN
  3137. SUBSTRING(wt.resource_description, NULLIF(CHARINDEX(N''subresource='', wt.resource_description), 0) + 12, COALESCE(NULLIF(CHARINDEX(N'' '', wt.resource_description, CHARINDEX(N''subresource='', wt.resource_description) + 12), 0), LEN(wt.resource_description) + 1) - CHARINDEX(N''subresource='', wt.resource_description) - 12)
  3138. ELSE
  3139. NULL
  3140. END AS metadata_resource,
  3141. CASE x.lock_type
  3142. WHEN N''metadatalock'' THEN
  3143. SUBSTRING(wt.resource_description, NULLIF(CHARINDEX(N''classid='', wt.resource_description), 0) + 8, COALESCE(NULLIF(CHARINDEX(N'' dbid='', wt.resource_description) - CHARINDEX(N''classid='', wt.resource_description), 0), LEN(wt.resource_description) + 1) - 8)
  3144. ELSE
  3145. NULL
  3146. END AS metadata_class_id
  3147. FROM
  3148. (
  3149. SELECT TOP(1)
  3150. LEFT(wt.resource_description, CHARINDEX(N'' '', wt.resource_description) - 1) COLLATE Latin1_General_Bin2 AS lock_type
  3151. ) AS x
  3152. FOR XML
  3153. PATH('''')
  3154. )
  3155. ELSE NULL
  3156. END AS block_info,
  3157. wt.wait_duration_ms,
  3158. wt.waiting_task_address
  3159. FROM
  3160. (
  3161. SELECT TOP(@i)
  3162. wt0.wait_type COLLATE Latin1_General_Bin2 AS wait_type,
  3163. wt0.resource_description COLLATE Latin1_General_Bin2 AS resource_description,
  3164. wt0.wait_duration_ms,
  3165. wt0.waiting_task_address,
  3166. CASE
  3167. WHEN wt0.blocking_session_id = p.blocked THEN
  3168. wt0.blocking_session_id
  3169. ELSE
  3170. NULL
  3171. END AS blocking_session_id
  3172. FROM sys.dm_os_waiting_tasks AS wt0
  3173. CROSS APPLY
  3174. (
  3175. SELECT TOP(1)
  3176. s0.blocked
  3177. FROM @sessions AS s0
  3178. WHERE
  3179. s0.session_id = wt0.session_id
  3180. AND COALESCE(s0.wait_type, N'''') <> N''OLEDB''
  3181. AND wt0.wait_type <> N''OLEDB''
  3182. ) AS p
  3183. ) AS wt
  3184. ) AS wt1
  3185. GROUP BY
  3186. wt1.wait_type,
  3187. wt1.waiting_task_address
  3188. ) AS wt2 ON
  3189. wt2.waiting_task_address = task_info.task_address
  3190. AND wt2.wait_duration_ms > 0
  3191. AND task_info.runnable_time IS NULL
  3192. GROUP BY
  3193. task_info.session_id,
  3194. task_info.request_id,
  3195. task_info.physical_io,
  3196. task_info.context_switches,
  3197. task_info.thread_CPU_snapshot,
  3198. task_info.num_tasks,
  3199. CASE
  3200. WHEN task_info.runnable_time IS NOT NULL THEN
  3201. ''RUNNABLE''
  3202. ELSE
  3203. wt2.wait_type
  3204. END
  3205. ) AS w1
  3206. ) AS waits
  3207. ORDER BY
  3208. waits.session_id,
  3209. waits.request_id,
  3210. waits.r
  3211. FOR XML
  3212. PATH(N''tasks''),
  3213. TYPE
  3214. ) AS tasks_raw (task_xml_raw)
  3215. ) AS tasks_final
  3216. CROSS APPLY tasks_final.task_xml.nodes(N''/tasks'') AS task_nodes (task_node)
  3217. WHERE
  3218. task_nodes.task_node.exist(N''session_id'') = 1
  3219. ) AS tasks ON
  3220. tasks.session_id = y.session_id
  3221. AND tasks.request_id = y.request_id
  3222. '
  3223. ELSE
  3224. ''
  3225. END +
  3226. 'LEFT OUTER HASH JOIN
  3227. (
  3228. SELECT TOP(@i)
  3229. t_info.session_id,
  3230. COALESCE(t_info.request_id, -1) AS request_id,
  3231. SUM(t_info.tempdb_allocations) AS tempdb_allocations,
  3232. SUM(t_info.tempdb_current) AS tempdb_current
  3233. FROM
  3234. (
  3235. SELECT TOP(@i)
  3236. tsu.session_id,
  3237. tsu.request_id,
  3238. tsu.user_objects_alloc_page_count +
  3239. tsu.internal_objects_alloc_page_count AS tempdb_allocations,
  3240. tsu.user_objects_alloc_page_count +
  3241. tsu.internal_objects_alloc_page_count -
  3242. tsu.user_objects_dealloc_page_count -
  3243. tsu.internal_objects_dealloc_page_count AS tempdb_current
  3244. FROM sys.dm_db_task_space_usage AS tsu
  3245. CROSS APPLY
  3246. (
  3247. SELECT TOP(1)
  3248. s0.session_id
  3249. FROM @sessions AS s0
  3250. WHERE
  3251. s0.session_id = tsu.session_id
  3252. ) AS p
  3253. UNION ALL
  3254. SELECT TOP(@i)
  3255. ssu.session_id,
  3256. NULL AS request_id,
  3257. ssu.user_objects_alloc_page_count +
  3258. ssu.internal_objects_alloc_page_count AS tempdb_allocations,
  3259. ssu.user_objects_alloc_page_count +
  3260. ssu.internal_objects_alloc_page_count -
  3261. ssu.user_objects_dealloc_page_count -
  3262. ssu.internal_objects_dealloc_page_count AS tempdb_current
  3263. FROM sys.dm_db_session_space_usage AS ssu
  3264. CROSS APPLY
  3265. (
  3266. SELECT TOP(1)
  3267. s0.session_id
  3268. FROM @sessions AS s0
  3269. WHERE
  3270. s0.session_id = ssu.session_id
  3271. ) AS p
  3272. ) AS t_info
  3273. GROUP BY
  3274. t_info.session_id,
  3275. COALESCE(t_info.request_id, -1)
  3276. ) AS tempdb_info ON
  3277. tempdb_info.session_id = y.session_id
  3278. AND tempdb_info.request_id =
  3279. CASE
  3280. WHEN y.status = N''sleeping'' THEN
  3281. -1
  3282. ELSE
  3283. y.request_id
  3284. END
  3285. ' +
  3286. CASE
  3287. WHEN
  3288. NOT
  3289. (
  3290. @get_avg_time = 1
  3291. AND @recursion = 1
  3292. ) THEN
  3293. ''
  3294. ELSE
  3295. 'LEFT OUTER HASH JOIN
  3296. (
  3297. SELECT TOP(@i)
  3298. *
  3299. FROM sys.dm_exec_query_stats
  3300. ) AS qs ON
  3301. qs.sql_handle = y.sql_handle
  3302. AND qs.plan_handle = y.plan_handle
  3303. AND qs.statement_start_offset = y.statement_start_offset
  3304. AND qs.statement_end_offset = y.statement_end_offset
  3305. '
  3306. END +
  3307. ') AS x
  3308. OPTION (KEEPFIXED PLAN, OPTIMIZE FOR (@i = 1)); ';
  3309. SET @sql_n = CONVERT(NVARCHAR(MAX), @sql);
  3310. SET @last_collection_start = GETDATE();
  3311. IF
  3312. @recursion = -1
  3313. AND @sys_info = 1
  3314. BEGIN;
  3315. SELECT
  3316. @first_collection_ms_ticks = ms_ticks
  3317. FROM sys.dm_os_sys_info;
  3318. END;
  3319. INSERT #sessions
  3320. (
  3321. recursion,
  3322. session_id,
  3323. request_id,
  3324. session_number,
  3325. elapsed_time,
  3326. avg_elapsed_time,
  3327. physical_io,
  3328. reads,
  3329. physical_reads,
  3330. writes,
  3331. tempdb_allocations,
  3332. tempdb_current,
  3333. CPU,
  3334. thread_CPU_snapshot,
  3335. context_switches,
  3336. used_memory,
  3337. tasks,
  3338. status,
  3339. wait_info,
  3340. transaction_id,
  3341. open_tran_count,
  3342. sql_handle,
  3343. statement_start_offset,
  3344. statement_end_offset,
  3345. sql_text,
  3346. plan_handle,
  3347. blocking_session_id,
  3348. percent_complete,
  3349. host_name,
  3350. login_name,
  3351. database_name,
  3352. program_name,
  3353. additional_info,
  3354. start_time,
  3355. login_time,
  3356. last_request_start_time
  3357. )
  3358. EXEC sp_executesql
  3359. @sql_n,
  3360. N'@recursion SMALLINT, @filter sysname, @not_filter sysname, @first_collection_ms_ticks BIGINT',
  3361. @recursion, @filter, @not_filter, @first_collection_ms_ticks;
  3362. --Collect transaction information?
  3363. IF
  3364. @recursion = 1
  3365. AND
  3366. (
  3367. @output_column_list LIKE '%|[tran_start_time|]%' ESCAPE '|'
  3368. OR @output_column_list LIKE '%|[tran_log_writes|]%' ESCAPE '|'
  3369. )
  3370. BEGIN;
  3371. DECLARE @i INT;
  3372. SET @i = 2147483647;
  3373. UPDATE s
  3374. SET
  3375. tran_start_time =
  3376. CONVERT
  3377. (
  3378. DATETIME,
  3379. LEFT
  3380. (
  3381. x.trans_info,
  3382. NULLIF(CHARINDEX(NCHAR(254) COLLATE Latin1_General_Bin2, x.trans_info) - 1, -1)
  3383. ),
  3384. 121
  3385. ),
  3386. tran_log_writes =
  3387. RIGHT
  3388. (
  3389. x.trans_info,
  3390. LEN(x.trans_info) - CHARINDEX(NCHAR(254) COLLATE Latin1_General_Bin2, x.trans_info)
  3391. )
  3392. FROM
  3393. (
  3394. SELECT TOP(@i)
  3395. trans_nodes.trans_node.value('(session_id/text())[1]', 'SMALLINT') AS session_id,
  3396. COALESCE(trans_nodes.trans_node.value('(request_id/text())[1]', 'INT'), 0) AS request_id,
  3397. trans_nodes.trans_node.value('(trans_info/text())[1]', 'NVARCHAR(4000)') AS trans_info
  3398. FROM
  3399. (
  3400. SELECT TOP(@i)
  3401. CONVERT
  3402. (
  3403. XML,
  3404. REPLACE
  3405. (
  3406. CONVERT(NVARCHAR(MAX), trans_raw.trans_xml_raw) COLLATE Latin1_General_Bin2,
  3407. N'</trans_info></trans><trans><trans_info>', N''
  3408. )
  3409. )
  3410. FROM
  3411. (
  3412. SELECT TOP(@i)
  3413. CASE u_trans.r
  3414. WHEN 1 THEN u_trans.session_id
  3415. ELSE NULL
  3416. END AS [session_id],
  3417. CASE u_trans.r
  3418. WHEN 1 THEN u_trans.request_id
  3419. ELSE NULL
  3420. END AS [request_id],
  3421. CONVERT
  3422. (
  3423. NVARCHAR(MAX),
  3424. CASE
  3425. WHEN u_trans.database_id IS NOT NULL THEN
  3426. CASE u_trans.r
  3427. WHEN 1 THEN COALESCE(CONVERT(NVARCHAR, u_trans.transaction_start_time, 121) + NCHAR(254), N'')
  3428. ELSE N''
  3429. END +
  3430. REPLACE
  3431. (
  3432. REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
  3433. REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
  3434. REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
  3435. CONVERT(VARCHAR(128), COALESCE(DB_NAME(u_trans.database_id), N'(null)')),
  3436. NCHAR(31),N'?'),NCHAR(30),N'?'),NCHAR(29),N'?'),NCHAR(28),N'?'),NCHAR(27),N'?'),NCHAR(26),N'?'),NCHAR(25),N'?'),NCHAR(24),N'?'),NCHAR(23),N'?'),NCHAR(22),N'?'),
  3437. NCHAR(21),N'?'),NCHAR(20),N'?'),NCHAR(19),N'?'),NCHAR(18),N'?'),NCHAR(17),N'?'),NCHAR(16),N'?'),NCHAR(15),N'?'),NCHAR(14),N'?'),NCHAR(12),N'?'),
  3438. NCHAR(11),N'?'),NCHAR(8),N'?'),NCHAR(7),N'?'),NCHAR(6),N'?'),NCHAR(5),N'?'),NCHAR(4),N'?'),NCHAR(3),N'?'),NCHAR(2),N'?'),NCHAR(1),N'?'),
  3439. NCHAR(0),
  3440. N'?'
  3441. ) +
  3442. N': ' +
  3443. CONVERT(NVARCHAR, u_trans.log_record_count) + N' (' + CONVERT(NVARCHAR, u_trans.log_kb_used) + N' kB)' +
  3444. N','
  3445. ELSE
  3446. N'N/A,'
  3447. END COLLATE Latin1_General_Bin2
  3448. ) AS [trans_info]
  3449. FROM
  3450. (
  3451. SELECT TOP(@i)
  3452. trans.*,
  3453. ROW_NUMBER() OVER
  3454. (
  3455. PARTITION BY
  3456. trans.session_id,
  3457. trans.request_id
  3458. ORDER BY
  3459. trans.transaction_start_time DESC
  3460. ) AS r
  3461. FROM
  3462. (
  3463. SELECT TOP(@i)
  3464. session_tran_map.session_id,
  3465. session_tran_map.request_id,
  3466. s_tran.database_id,
  3467. COALESCE(SUM(s_tran.database_transaction_log_record_count), 0) AS log_record_count,
  3468. COALESCE(SUM(s_tran.database_transaction_log_bytes_used), 0) / 1024 AS log_kb_used,
  3469. MIN(s_tran.database_transaction_begin_time) AS transaction_start_time
  3470. FROM
  3471. (
  3472. SELECT TOP(@i)
  3473. *
  3474. FROM sys.dm_tran_active_transactions
  3475. WHERE
  3476. transaction_begin_time <= @last_collection_start
  3477. ) AS a_tran
  3478. INNER HASH JOIN
  3479. (
  3480. SELECT TOP(@i)
  3481. *
  3482. FROM sys.dm_tran_database_transactions
  3483. WHERE
  3484. database_id < 32767
  3485. ) AS s_tran ON
  3486. s_tran.transaction_id = a_tran.transaction_id
  3487. LEFT OUTER HASH JOIN
  3488. (
  3489. SELECT TOP(@i)
  3490. *
  3491. FROM sys.dm_tran_session_transactions
  3492. ) AS tst ON
  3493. s_tran.transaction_id = tst.transaction_id
  3494. CROSS APPLY
  3495. (
  3496. SELECT TOP(1)
  3497. s3.session_id,
  3498. s3.request_id
  3499. FROM
  3500. (
  3501. SELECT TOP(1)
  3502. s1.session_id,
  3503. s1.request_id
  3504. FROM #sessions AS s1
  3505. WHERE
  3506. s1.transaction_id = s_tran.transaction_id
  3507. AND s1.recursion = 1
  3508. UNION ALL
  3509. SELECT TOP(1)
  3510. s2.session_id,
  3511. s2.request_id
  3512. FROM #sessions AS s2
  3513. WHERE
  3514. s2.session_id = tst.session_id
  3515. AND s2.recursion = 1
  3516. ) AS s3
  3517. ORDER BY
  3518. s3.request_id
  3519. ) AS session_tran_map
  3520. GROUP BY
  3521. session_tran_map.session_id,
  3522. session_tran_map.request_id,
  3523. s_tran.database_id
  3524. ) AS trans
  3525. ) AS u_trans
  3526. FOR XML
  3527. PATH('trans'),
  3528. TYPE
  3529. ) AS trans_raw (trans_xml_raw)
  3530. ) AS trans_final (trans_xml)
  3531. CROSS APPLY trans_final.trans_xml.nodes('/trans') AS trans_nodes (trans_node)
  3532. ) AS x
  3533. INNER HASH JOIN #sessions AS s ON
  3534. s.session_id = x.session_id
  3535. AND s.request_id = x.request_id
  3536. OPTION (OPTIMIZE FOR (@i = 1));
  3537. END;
  3538. --Variables for text and plan collection
  3539. DECLARE
  3540. @session_id SMALLINT,
  3541. @request_id INT,
  3542. @sql_handle VARBINARY(64),
  3543. @plan_handle VARBINARY(64),
  3544. @statement_start_offset INT,
  3545. @statement_end_offset INT,
  3546. @start_time DATETIME,
  3547. @database_name sysname;
  3548. IF
  3549. @recursion = 1
  3550. AND @output_column_list LIKE '%|[sql_text|]%' ESCAPE '|'
  3551. BEGIN;
  3552. DECLARE sql_cursor
  3553. CURSOR LOCAL FAST_FORWARD
  3554. FOR
  3555. SELECT
  3556. session_id,
  3557. request_id,
  3558. sql_handle,
  3559. statement_start_offset,
  3560. statement_end_offset
  3561. FROM #sessions
  3562. WHERE
  3563. recursion = 1
  3564. AND sql_handle IS NOT NULL
  3565. OPTION (KEEPFIXED PLAN);
  3566. OPEN sql_cursor;
  3567. FETCH NEXT FROM sql_cursor
  3568. INTO
  3569. @session_id,
  3570. @request_id,
  3571. @sql_handle,
  3572. @statement_start_offset,
  3573. @statement_end_offset;
  3574. --Wait up to 5 ms for the SQL text, then give up
  3575. SET LOCK_TIMEOUT 5;
  3576. WHILE @@FETCH_STATUS = 0
  3577. BEGIN;
  3578. BEGIN TRY;
  3579. UPDATE s
  3580. SET
  3581. s.sql_text =
  3582. (
  3583. SELECT
  3584. REPLACE
  3585. (
  3586. REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
  3587. REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
  3588. REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
  3589. N'--' + NCHAR(13) + NCHAR(10) +
  3590. CASE
  3591. WHEN @get_full_inner_text = 1 THEN est.text
  3592. WHEN LEN(est.text) < (@statement_end_offset / 2) + 1 THEN est.text
  3593. WHEN SUBSTRING(est.text, (@statement_start_offset/2), 2) LIKE N'[a-zA-Z0-9][a-zA-Z0-9]' THEN est.text
  3594. ELSE
  3595. CASE
  3596. WHEN @statement_start_offset > 0 THEN
  3597. SUBSTRING
  3598. (
  3599. est.text,
  3600. ((@statement_start_offset/2) + 1),
  3601. (
  3602. CASE
  3603. WHEN @statement_end_offset = -1 THEN 2147483647
  3604. ELSE ((@statement_end_offset - @statement_start_offset)/2) + 1
  3605. END
  3606. )
  3607. )
  3608. ELSE RTRIM(LTRIM(est.text))
  3609. END
  3610. END +
  3611. NCHAR(13) + NCHAR(10) + N'--' COLLATE Latin1_General_Bin2,
  3612. NCHAR(31),N'?'),NCHAR(30),N'?'),NCHAR(29),N'?'),NCHAR(28),N'?'),NCHAR(27),N'?'),NCHAR(26),N'?'),NCHAR(25),N'?'),NCHAR(24),N'?'),NCHAR(23),N'?'),NCHAR(22),N'?'),
  3613. NCHAR(21),N'?'),NCHAR(20),N'?'),NCHAR(19),N'?'),NCHAR(18),N'?'),NCHAR(17),N'?'),NCHAR(16),N'?'),NCHAR(15),N'?'),NCHAR(14),N'?'),NCHAR(12),N'?'),
  3614. NCHAR(11),N'?'),NCHAR(8),N'?'),NCHAR(7),N'?'),NCHAR(6),N'?'),NCHAR(5),N'?'),NCHAR(4),N'?'),NCHAR(3),N'?'),NCHAR(2),N'?'),NCHAR(1),N'?'),
  3615. NCHAR(0),
  3616. N''
  3617. ) AS [processing-instruction(query)]
  3618. FOR XML
  3619. PATH(''),
  3620. TYPE
  3621. ),
  3622. s.statement_start_offset =
  3623. CASE
  3624. WHEN LEN(est.text) < (@statement_end_offset / 2) + 1 THEN 0
  3625. WHEN SUBSTRING(CONVERT(VARCHAR(MAX), est.text), (@statement_start_offset/2), 2) LIKE '[a-zA-Z0-9][a-zA-Z0-9]' THEN 0
  3626. ELSE @statement_start_offset
  3627. END,
  3628. s.statement_end_offset =
  3629. CASE
  3630. WHEN LEN(est.text) < (@statement_end_offset / 2) + 1 THEN -1
  3631. WHEN SUBSTRING(CONVERT(VARCHAR(MAX), est.text), (@statement_start_offset/2), 2) LIKE '[a-zA-Z0-9][a-zA-Z0-9]' THEN -1
  3632. ELSE @statement_end_offset
  3633. END
  3634. FROM
  3635. #sessions AS s,
  3636. (
  3637. SELECT TOP(1)
  3638. text
  3639. FROM
  3640. (
  3641. SELECT
  3642. text,
  3643. 0 AS row_num
  3644. FROM sys.dm_exec_sql_text(@sql_handle)
  3645. UNION ALL
  3646. SELECT
  3647. NULL,
  3648. 1 AS row_num
  3649. ) AS est0
  3650. ORDER BY
  3651. row_num
  3652. ) AS est
  3653. WHERE
  3654. s.session_id = @session_id
  3655. AND s.request_id = @request_id
  3656. AND s.recursion = 1
  3657. OPTION (KEEPFIXED PLAN);
  3658. END TRY
  3659. BEGIN CATCH;
  3660. UPDATE s
  3661. SET
  3662. s.sql_text =
  3663. CASE ERROR_NUMBER()
  3664. WHEN 1222 THEN '<timeout_exceeded />'
  3665. ELSE '<error message="' + ERROR_MESSAGE() + '" />'
  3666. END
  3667. FROM #sessions AS s
  3668. WHERE
  3669. s.session_id = @session_id
  3670. AND s.request_id = @request_id
  3671. AND s.recursion = 1
  3672. OPTION (KEEPFIXED PLAN);
  3673. END CATCH;
  3674. FETCH NEXT FROM sql_cursor
  3675. INTO
  3676. @session_id,
  3677. @request_id,
  3678. @sql_handle,
  3679. @statement_start_offset,
  3680. @statement_end_offset;
  3681. END;
  3682. --Return this to the default
  3683. SET LOCK_TIMEOUT -1;
  3684. CLOSE sql_cursor;
  3685. DEALLOCATE sql_cursor;
  3686. END;
  3687. IF
  3688. @get_outer_command = 1
  3689. AND @recursion = 1
  3690. AND @output_column_list LIKE '%|[sql_command|]%' ESCAPE '|'
  3691. BEGIN;
  3692. DECLARE @buffer_results TABLE
  3693. (
  3694. EventType VARCHAR(30),
  3695. Parameters INT,
  3696. EventInfo NVARCHAR(4000),
  3697. start_time DATETIME,
  3698. session_number INT IDENTITY(1,1) NOT NULL PRIMARY KEY
  3699. );
  3700. DECLARE buffer_cursor
  3701. CURSOR LOCAL FAST_FORWARD
  3702. FOR
  3703. SELECT
  3704. session_id,
  3705. MAX(start_time) AS start_time
  3706. FROM #sessions
  3707. WHERE
  3708. recursion = 1
  3709. GROUP BY
  3710. session_id
  3711. ORDER BY
  3712. session_id
  3713. OPTION (KEEPFIXED PLAN);
  3714. OPEN buffer_cursor;
  3715. FETCH NEXT FROM buffer_cursor
  3716. INTO
  3717. @session_id,
  3718. @start_time;
  3719. WHILE @@FETCH_STATUS = 0
  3720. BEGIN;
  3721. BEGIN TRY;
  3722. --In SQL Server 2008, DBCC INPUTBUFFER will throw
  3723. --an exception if the session no longer exists
  3724. INSERT @buffer_results
  3725. (
  3726. EventType,
  3727. Parameters,
  3728. EventInfo
  3729. )
  3730. EXEC sp_executesql
  3731. N'DBCC INPUTBUFFER(@session_id) WITH NO_INFOMSGS;',
  3732. N'@session_id SMALLINT',
  3733. @session_id;
  3734. UPDATE br
  3735. SET
  3736. br.start_time = @start_time
  3737. FROM @buffer_results AS br
  3738. WHERE
  3739. br.session_number =
  3740. (
  3741. SELECT MAX(br2.session_number)
  3742. FROM @buffer_results br2
  3743. );
  3744. END TRY
  3745. BEGIN CATCH
  3746. END CATCH;
  3747. FETCH NEXT FROM buffer_cursor
  3748. INTO
  3749. @session_id,
  3750. @start_time;
  3751. END;
  3752. UPDATE s
  3753. SET
  3754. sql_command =
  3755. (
  3756. SELECT
  3757. REPLACE
  3758. (
  3759. REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
  3760. REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
  3761. REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
  3762. CONVERT
  3763. (
  3764. NVARCHAR(MAX),
  3765. N'--' + NCHAR(13) + NCHAR(10) + br.EventInfo + NCHAR(13) + NCHAR(10) + N'--' COLLATE Latin1_General_Bin2
  3766. ),
  3767. NCHAR(31),N'?'),NCHAR(30),N'?'),NCHAR(29),N'?'),NCHAR(28),N'?'),NCHAR(27),N'?'),NCHAR(26),N'?'),NCHAR(25),N'?'),NCHAR(24),N'?'),NCHAR(23),N'?'),NCHAR(22),N'?'),
  3768. NCHAR(21),N'?'),NCHAR(20),N'?'),NCHAR(19),N'?'),NCHAR(18),N'?'),NCHAR(17),N'?'),NCHAR(16),N'?'),NCHAR(15),N'?'),NCHAR(14),N'?'),NCHAR(12),N'?'),
  3769. NCHAR(11),N'?'),NCHAR(8),N'?'),NCHAR(7),N'?'),NCHAR(6),N'?'),NCHAR(5),N'?'),NCHAR(4),N'?'),NCHAR(3),N'?'),NCHAR(2),N'?'),NCHAR(1),N'?'),
  3770. NCHAR(0),
  3771. N''
  3772. ) AS [processing-instruction(query)]
  3773. FROM @buffer_results AS br
  3774. WHERE
  3775. br.session_number = s.session_number
  3776. AND br.start_time = s.start_time
  3777. AND
  3778. (
  3779. (
  3780. s.start_time = s.last_request_start_time
  3781. AND EXISTS
  3782. (
  3783. SELECT *
  3784. FROM sys.dm_exec_requests r2
  3785. WHERE
  3786. r2.session_id = s.session_id
  3787. AND r2.request_id = s.request_id
  3788. AND r2.start_time = s.start_time
  3789. )
  3790. )
  3791. OR
  3792. (
  3793. s.request_id = 0
  3794. AND EXISTS
  3795. (
  3796. SELECT *
  3797. FROM sys.dm_exec_sessions s2
  3798. WHERE
  3799. s2.session_id = s.session_id
  3800. AND s2.last_request_start_time = s.last_request_start_time
  3801. )
  3802. )
  3803. )
  3804. FOR XML
  3805. PATH(''),
  3806. TYPE
  3807. )
  3808. FROM #sessions AS s
  3809. WHERE
  3810. recursion = 1
  3811. OPTION (KEEPFIXED PLAN);
  3812. CLOSE buffer_cursor;
  3813. DEALLOCATE buffer_cursor;
  3814. END;
  3815. IF
  3816. @get_plans >= 1
  3817. AND @recursion = 1
  3818. AND @output_column_list LIKE '%|[query_plan|]%' ESCAPE '|'
  3819. BEGIN;
  3820. DECLARE @live_plan BIT;
  3821. SET @live_plan = ISNULL(CONVERT(BIT, SIGN(OBJECT_ID('sys.dm_exec_query_statistics_xml'))), 0)
  3822. DECLARE plan_cursor
  3823. CURSOR LOCAL FAST_FORWARD
  3824. FOR
  3825. SELECT
  3826. session_id,
  3827. request_id,
  3828. plan_handle,
  3829. statement_start_offset,
  3830. statement_end_offset
  3831. FROM #sessions
  3832. WHERE
  3833. recursion = 1
  3834. AND plan_handle IS NOT NULL
  3835. OPTION (KEEPFIXED PLAN);
  3836. OPEN plan_cursor;
  3837. FETCH NEXT FROM plan_cursor
  3838. INTO
  3839. @session_id,
  3840. @request_id,
  3841. @plan_handle,
  3842. @statement_start_offset,
  3843. @statement_end_offset;
  3844. --Wait up to 5 ms for a query plan, then give up
  3845. SET LOCK_TIMEOUT 5;
  3846. WHILE @@FETCH_STATUS = 0
  3847. BEGIN;
  3848. DECLARE @query_plan XML;
  3849. SET @query_plan = NULL;
  3850. IF @live_plan = 1
  3851. BEGIN;
  3852. BEGIN TRY;
  3853. SELECT
  3854. @query_plan = x.query_plan
  3855. FROM sys.dm_exec_query_statistics_xml(@session_id) AS x;
  3856. IF
  3857. @query_plan IS NOT NULL
  3858. AND EXISTS
  3859. (
  3860. SELECT
  3861. *
  3862. FROM sys.dm_exec_requests AS r
  3863. WHERE
  3864. r.session_id = @session_id
  3865. AND r.request_id = @request_id
  3866. AND r.plan_handle = @plan_handle
  3867. AND r.statement_start_offset = @statement_start_offset
  3868. AND r.statement_end_offset = @statement_end_offset
  3869. )
  3870. BEGIN;
  3871. UPDATE s
  3872. SET
  3873. s.query_plan = @query_plan
  3874. FROM #sessions AS s
  3875. WHERE
  3876. s.session_id = @session_id
  3877. AND s.request_id = @request_id
  3878. AND s.recursion = 1
  3879. OPTION (KEEPFIXED PLAN);
  3880. END;
  3881. END TRY
  3882. BEGIN CATCH;
  3883. SET @query_plan = NULL;
  3884. END CATCH;
  3885. END;
  3886. IF @query_plan IS NULL
  3887. BEGIN;
  3888. BEGIN TRY;
  3889. UPDATE s
  3890. SET
  3891. s.query_plan =
  3892. (
  3893. SELECT
  3894. CONVERT(xml, query_plan)
  3895. FROM sys.dm_exec_text_query_plan
  3896. (
  3897. @plan_handle,
  3898. CASE @get_plans
  3899. WHEN 1 THEN
  3900. @statement_start_offset
  3901. ELSE
  3902. 0
  3903. END,
  3904. CASE @get_plans
  3905. WHEN 1 THEN
  3906. @statement_end_offset
  3907. ELSE
  3908. -1
  3909. END
  3910. )
  3911. )
  3912. FROM #sessions AS s
  3913. WHERE
  3914. s.session_id = @session_id
  3915. AND s.request_id = @request_id
  3916. AND s.recursion = 1
  3917. OPTION (KEEPFIXED PLAN);
  3918. END TRY
  3919. BEGIN CATCH;
  3920. IF ERROR_NUMBER() = 6335
  3921. BEGIN;
  3922. UPDATE s
  3923. SET
  3924. s.query_plan =
  3925. (
  3926. SELECT
  3927. N'--' + NCHAR(13) + NCHAR(10) +
  3928. N'-- Could not render showplan due to XML data type limitations. ' + NCHAR(13) + NCHAR(10) +
  3929. N'-- To see the graphical plan save the XML below as a .SQLPLAN file and re-open in SSMS.' + NCHAR(13) + NCHAR(10) +
  3930. N'--' + NCHAR(13) + NCHAR(10) +
  3931. REPLACE(qp.query_plan, N'<RelOp', NCHAR(13)+NCHAR(10)+N'<RelOp') +
  3932. NCHAR(13) + NCHAR(10) + N'--' COLLATE Latin1_General_Bin2 AS [processing-instruction(query_plan)]
  3933. FROM sys.dm_exec_text_query_plan
  3934. (
  3935. @plan_handle,
  3936. CASE @get_plans
  3937. WHEN 1 THEN
  3938. @statement_start_offset
  3939. ELSE
  3940. 0
  3941. END,
  3942. CASE @get_plans
  3943. WHEN 1 THEN
  3944. @statement_end_offset
  3945. ELSE
  3946. -1
  3947. END
  3948. ) AS qp
  3949. FOR XML
  3950. PATH(''),
  3951. TYPE
  3952. )
  3953. FROM #sessions AS s
  3954. WHERE
  3955. s.session_id = @session_id
  3956. AND s.request_id = @request_id
  3957. AND s.recursion = 1
  3958. OPTION (KEEPFIXED PLAN);
  3959. END;
  3960. ELSE
  3961. BEGIN;
  3962. UPDATE s
  3963. SET
  3964. s.query_plan =
  3965. CASE ERROR_NUMBER()
  3966. WHEN 1222 THEN '<timeout_exceeded />'
  3967. ELSE '<error message="' + ERROR_MESSAGE() + '" />'
  3968. END
  3969. FROM #sessions AS s
  3970. WHERE
  3971. s.session_id = @session_id
  3972. AND s.request_id = @request_id
  3973. AND s.recursion = 1
  3974. OPTION (KEEPFIXED PLAN);
  3975. END;
  3976. END CATCH;
  3977. END;
  3978. FETCH NEXT FROM plan_cursor
  3979. INTO
  3980. @session_id,
  3981. @request_id,
  3982. @plan_handle,
  3983. @statement_start_offset,
  3984. @statement_end_offset;
  3985. END;
  3986. --Return this to the default
  3987. SET LOCK_TIMEOUT -1;
  3988. CLOSE plan_cursor;
  3989. DEALLOCATE plan_cursor;
  3990. END;
  3991. IF
  3992. @get_locks = 1
  3993. AND @recursion = 1
  3994. AND @output_column_list LIKE '%|[locks|]%' ESCAPE '|'
  3995. BEGIN;
  3996. DECLARE locks_cursor
  3997. CURSOR LOCAL FAST_FORWARD
  3998. FOR
  3999. SELECT DISTINCT
  4000. database_name
  4001. FROM #locks
  4002. WHERE
  4003. EXISTS
  4004. (
  4005. SELECT *
  4006. FROM #sessions AS s
  4007. WHERE
  4008. s.session_id = #locks.session_id
  4009. AND recursion = 1
  4010. )
  4011. AND database_name <> '(null)'
  4012. OPTION (KEEPFIXED PLAN);
  4013. OPEN locks_cursor;
  4014. FETCH NEXT FROM locks_cursor
  4015. INTO
  4016. @database_name;
  4017. WHILE @@FETCH_STATUS = 0
  4018. BEGIN;
  4019. BEGIN TRY;
  4020. SET @sql_n = CONVERT(NVARCHAR(MAX), '') +
  4021. 'UPDATE l ' +
  4022. 'SET ' +
  4023. 'object_name = ' +
  4024. 'REPLACE ' +
  4025. '( ' +
  4026. 'REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( ' +
  4027. 'REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( ' +
  4028. 'REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( ' +
  4029. 'o.name COLLATE Latin1_General_Bin2, ' +
  4030. 'NCHAR(31),N''?''),NCHAR(30),N''?''),NCHAR(29),N''?''),NCHAR(28),N''?''),NCHAR(27),N''?''),NCHAR(26),N''?''),NCHAR(25),N''?''),NCHAR(24),N''?''),NCHAR(23),N''?''),NCHAR(22),N''?''), ' +
  4031. 'NCHAR(21),N''?''),NCHAR(20),N''?''),NCHAR(19),N''?''),NCHAR(18),N''?''),NCHAR(17),N''?''),NCHAR(16),N''?''),NCHAR(15),N''?''),NCHAR(14),N''?''),NCHAR(12),N''?''), ' +
  4032. 'NCHAR(11),N''?''),NCHAR(8),N''?''),NCHAR(7),N''?''),NCHAR(6),N''?''),NCHAR(5),N''?''),NCHAR(4),N''?''),NCHAR(3),N''?''),NCHAR(2),N''?''),NCHAR(1),N''?''), ' +
  4033. 'NCHAR(0), ' +
  4034. N''''' ' +
  4035. '), ' +
  4036. 'index_name = ' +
  4037. 'REPLACE ' +
  4038. '( ' +
  4039. 'REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( ' +
  4040. 'REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( ' +
  4041. 'REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( ' +
  4042. 'i.name COLLATE Latin1_General_Bin2, ' +
  4043. 'NCHAR(31),N''?''),NCHAR(30),N''?''),NCHAR(29),N''?''),NCHAR(28),N''?''),NCHAR(27),N''?''),NCHAR(26),N''?''),NCHAR(25),N''?''),NCHAR(24),N''?''),NCHAR(23),N''?''),NCHAR(22),N''?''), ' +
  4044. 'NCHAR(21),N''?''),NCHAR(20),N''?''),NCHAR(19),N''?''),NCHAR(18),N''?''),NCHAR(17),N''?''),NCHAR(16),N''?''),NCHAR(15),N''?''),NCHAR(14),N''?''),NCHAR(12),N''?''), ' +
  4045. 'NCHAR(11),N''?''),NCHAR(8),N''?''),NCHAR(7),N''?''),NCHAR(6),N''?''),NCHAR(5),N''?''),NCHAR(4),N''?''),NCHAR(3),N''?''),NCHAR(2),N''?''),NCHAR(1),N''?''), ' +
  4046. 'NCHAR(0), ' +
  4047. N''''' ' +
  4048. '), ' +
  4049. 'schema_name = ' +
  4050. 'REPLACE ' +
  4051. '( ' +
  4052. 'REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( ' +
  4053. 'REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( ' +
  4054. 'REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( ' +
  4055. 's.name COLLATE Latin1_General_Bin2, ' +
  4056. 'NCHAR(31),N''?''),NCHAR(30),N''?''),NCHAR(29),N''?''),NCHAR(28),N''?''),NCHAR(27),N''?''),NCHAR(26),N''?''),NCHAR(25),N''?''),NCHAR(24),N''?''),NCHAR(23),N''?''),NCHAR(22),N''?''), ' +
  4057. 'NCHAR(21),N''?''),NCHAR(20),N''?''),NCHAR(19),N''?''),NCHAR(18),N''?''),NCHAR(17),N''?''),NCHAR(16),N''?''),NCHAR(15),N''?''),NCHAR(14),N''?''),NCHAR(12),N''?''), ' +
  4058. 'NCHAR(11),N''?''),NCHAR(8),N''?''),NCHAR(7),N''?''),NCHAR(6),N''?''),NCHAR(5),N''?''),NCHAR(4),N''?''),NCHAR(3),N''?''),NCHAR(2),N''?''),NCHAR(1),N''?''), ' +
  4059. 'NCHAR(0), ' +
  4060. N''''' ' +
  4061. '), ' +
  4062. 'principal_name = ' +
  4063. 'REPLACE ' +
  4064. '( ' +
  4065. 'REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( ' +
  4066. 'REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( ' +
  4067. 'REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( ' +
  4068. 'dp.name COLLATE Latin1_General_Bin2, ' +
  4069. 'NCHAR(31),N''?''),NCHAR(30),N''?''),NCHAR(29),N''?''),NCHAR(28),N''?''),NCHAR(27),N''?''),NCHAR(26),N''?''),NCHAR(25),N''?''),NCHAR(24),N''?''),NCHAR(23),N''?''),NCHAR(22),N''?''), ' +
  4070. 'NCHAR(21),N''?''),NCHAR(20),N''?''),NCHAR(19),N''?''),NCHAR(18),N''?''),NCHAR(17),N''?''),NCHAR(16),N''?''),NCHAR(15),N''?''),NCHAR(14),N''?''),NCHAR(12),N''?''), ' +
  4071. 'NCHAR(11),N''?''),NCHAR(8),N''?''),NCHAR(7),N''?''),NCHAR(6),N''?''),NCHAR(5),N''?''),NCHAR(4),N''?''),NCHAR(3),N''?''),NCHAR(2),N''?''),NCHAR(1),N''?''), ' +
  4072. 'NCHAR(0), ' +
  4073. N''''' ' +
  4074. ') ' +
  4075. 'FROM #locks AS l ' +
  4076. 'LEFT OUTER JOIN ' + QUOTENAME(@database_name) + '.sys.allocation_units AS au ON ' +
  4077. 'au.allocation_unit_id = l.allocation_unit_id ' +
  4078. 'LEFT OUTER JOIN ' + QUOTENAME(@database_name) + '.sys.partitions AS p ON ' +
  4079. 'p.hobt_id = ' +
  4080. 'COALESCE ' +
  4081. '( ' +
  4082. 'l.hobt_id, ' +
  4083. 'CASE ' +
  4084. 'WHEN au.type IN (1, 3) THEN au.container_id ' +
  4085. 'ELSE NULL ' +
  4086. 'END ' +
  4087. ') ' +
  4088. 'LEFT OUTER JOIN ' + QUOTENAME(@database_name) + '.sys.partitions AS p1 ON ' +
  4089. 'l.hobt_id IS NULL ' +
  4090. 'AND au.type = 2 ' +
  4091. 'AND p1.partition_id = au.container_id ' +
  4092. 'LEFT OUTER JOIN ' + QUOTENAME(@database_name) + '.sys.objects AS o ON ' +
  4093. 'o.object_id = COALESCE(l.object_id, p.object_id, p1.object_id) ' +
  4094. 'LEFT OUTER JOIN ' + QUOTENAME(@database_name) + '.sys.indexes AS i ON ' +
  4095. 'i.object_id = COALESCE(l.object_id, p.object_id, p1.object_id) ' +
  4096. 'AND i.index_id = COALESCE(l.index_id, p.index_id, p1.index_id) ' +
  4097. 'LEFT OUTER JOIN ' + QUOTENAME(@database_name) + '.sys.schemas AS s ON ' +
  4098. 's.schema_id = COALESCE(l.schema_id, o.schema_id) ' +
  4099. 'LEFT OUTER JOIN ' + QUOTENAME(@database_name) + '.sys.database_principals AS dp ON ' +
  4100. 'dp.principal_id = l.principal_id ' +
  4101. 'WHERE ' +
  4102. 'l.database_name = @database_name ' +
  4103. 'OPTION (KEEPFIXED PLAN); ';
  4104. EXEC sp_executesql
  4105. @sql_n,
  4106. N'@database_name sysname',
  4107. @database_name;
  4108. END TRY
  4109. BEGIN CATCH;
  4110. UPDATE #locks
  4111. SET
  4112. query_error =
  4113. REPLACE
  4114. (
  4115. REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
  4116. REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
  4117. REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
  4118. CONVERT
  4119. (
  4120. NVARCHAR(MAX),
  4121. ERROR_MESSAGE() COLLATE Latin1_General_Bin2
  4122. ),
  4123. NCHAR(31),N'?'),NCHAR(30),N'?'),NCHAR(29),N'?'),NCHAR(28),N'?'),NCHAR(27),N'?'),NCHAR(26),N'?'),NCHAR(25),N'?'),NCHAR(24),N'?'),NCHAR(23),N'?'),NCHAR(22),N'?'),
  4124. NCHAR(21),N'?'),NCHAR(20),N'?'),NCHAR(19),N'?'),NCHAR(18),N'?'),NCHAR(17),N'?'),NCHAR(16),N'?'),NCHAR(15),N'?'),NCHAR(14),N'?'),NCHAR(12),N'?'),
  4125. NCHAR(11),N'?'),NCHAR(8),N'?'),NCHAR(7),N'?'),NCHAR(6),N'?'),NCHAR(5),N'?'),NCHAR(4),N'?'),NCHAR(3),N'?'),NCHAR(2),N'?'),NCHAR(1),N'?'),
  4126. NCHAR(0),
  4127. N''
  4128. )
  4129. WHERE
  4130. database_name = @database_name
  4131. OPTION (KEEPFIXED PLAN);
  4132. END CATCH;
  4133. FETCH NEXT FROM locks_cursor
  4134. INTO
  4135. @database_name;
  4136. END;
  4137. CLOSE locks_cursor;
  4138. DEALLOCATE locks_cursor;
  4139. CREATE CLUSTERED INDEX IX_SRD ON #locks (session_id, request_id, database_name);
  4140. UPDATE s
  4141. SET
  4142. s.locks =
  4143. (
  4144. SELECT
  4145. REPLACE
  4146. (
  4147. REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
  4148. REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
  4149. REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
  4150. CONVERT
  4151. (
  4152. NVARCHAR(MAX),
  4153. l1.database_name COLLATE Latin1_General_Bin2
  4154. ),
  4155. NCHAR(31),N'?'),NCHAR(30),N'?'),NCHAR(29),N'?'),NCHAR(28),N'?'),NCHAR(27),N'?'),NCHAR(26),N'?'),NCHAR(25),N'?'),NCHAR(24),N'?'),NCHAR(23),N'?'),NCHAR(22),N'?'),
  4156. NCHAR(21),N'?'),NCHAR(20),N'?'),NCHAR(19),N'?'),NCHAR(18),N'?'),NCHAR(17),N'?'),NCHAR(16),N'?'),NCHAR(15),N'?'),NCHAR(14),N'?'),NCHAR(12),N'?'),
  4157. NCHAR(11),N'?'),NCHAR(8),N'?'),NCHAR(7),N'?'),NCHAR(6),N'?'),NCHAR(5),N'?'),NCHAR(4),N'?'),NCHAR(3),N'?'),NCHAR(2),N'?'),NCHAR(1),N'?'),
  4158. NCHAR(0),
  4159. N''
  4160. ) AS [Database/@name],
  4161. MIN(l1.query_error) AS [Database/@query_error],
  4162. (
  4163. SELECT
  4164. l2.request_mode AS [Lock/@request_mode],
  4165. l2.request_status AS [Lock/@request_status],
  4166. COUNT(*) AS [Lock/@request_count]
  4167. FROM #locks AS l2
  4168. WHERE
  4169. l1.session_id = l2.session_id
  4170. AND l1.request_id = l2.request_id
  4171. AND l2.database_name = l1.database_name
  4172. AND l2.resource_type = 'DATABASE'
  4173. GROUP BY
  4174. l2.request_mode,
  4175. l2.request_status
  4176. FOR XML
  4177. PATH(''),
  4178. TYPE
  4179. ) AS [Database/Locks],
  4180. (
  4181. SELECT
  4182. COALESCE(l3.object_name, '(null)') AS [Object/@name],
  4183. l3.schema_name AS [Object/@schema_name],
  4184. (
  4185. SELECT
  4186. l4.resource_type AS [Lock/@resource_type],
  4187. l4.page_type AS [Lock/@page_type],
  4188. l4.index_name AS [Lock/@index_name],
  4189. CASE
  4190. WHEN l4.object_name IS NULL THEN l4.schema_name
  4191. ELSE NULL
  4192. END AS [Lock/@schema_name],
  4193. l4.principal_name AS [Lock/@principal_name],
  4194. l4.resource_description AS [Lock/@resource_description],
  4195. l4.request_mode AS [Lock/@request_mode],
  4196. l4.request_status AS [Lock/@request_status],
  4197. SUM(l4.request_count) AS [Lock/@request_count]
  4198. FROM #locks AS l4
  4199. WHERE
  4200. l4.session_id = l3.session_id
  4201. AND l4.request_id = l3.request_id
  4202. AND l3.database_name = l4.database_name
  4203. AND COALESCE(l3.object_name, '(null)') = COALESCE(l4.object_name, '(null)')
  4204. AND COALESCE(l3.schema_name, '') = COALESCE(l4.schema_name, '')
  4205. AND l4.resource_type <> 'DATABASE'
  4206. GROUP BY
  4207. l4.resource_type,
  4208. l4.page_type,
  4209. l4.index_name,
  4210. CASE
  4211. WHEN l4.object_name IS NULL THEN l4.schema_name
  4212. ELSE NULL
  4213. END,
  4214. l4.principal_name,
  4215. l4.resource_description,
  4216. l4.request_mode,
  4217. l4.request_status
  4218. FOR XML
  4219. PATH(''),
  4220. TYPE
  4221. ) AS [Object/Locks]
  4222. FROM #locks AS l3
  4223. WHERE
  4224. l3.session_id = l1.session_id
  4225. AND l3.request_id = l1.request_id
  4226. AND l3.database_name = l1.database_name
  4227. AND l3.resource_type <> 'DATABASE'
  4228. GROUP BY
  4229. l3.session_id,
  4230. l3.request_id,
  4231. l3.database_name,
  4232. COALESCE(l3.object_name, '(null)'),
  4233. l3.schema_name
  4234. FOR XML
  4235. PATH(''),
  4236. TYPE
  4237. ) AS [Database/Objects]
  4238. FROM #locks AS l1
  4239. WHERE
  4240. l1.session_id = s.session_id
  4241. AND l1.request_id = s.request_id
  4242. AND l1.start_time IN (s.start_time, s.last_request_start_time)
  4243. AND s.recursion = 1
  4244. GROUP BY
  4245. l1.session_id,
  4246. l1.request_id,
  4247. l1.database_name
  4248. FOR XML
  4249. PATH(''),
  4250. TYPE
  4251. )
  4252. FROM #sessions s
  4253. OPTION (KEEPFIXED PLAN);
  4254. END;
  4255. IF
  4256. @find_block_leaders = 1
  4257. AND @recursion = 1
  4258. AND @output_column_list LIKE '%|[blocked_session_count|]%' ESCAPE '|'
  4259. BEGIN;
  4260. WITH
  4261. blockers AS
  4262. (
  4263. SELECT
  4264. session_id,
  4265. session_id AS top_level_session_id,
  4266. CONVERT(VARCHAR(8000), '.' + CONVERT(VARCHAR(8000), session_id) + '.') AS the_path
  4267. FROM #sessions
  4268. WHERE
  4269. recursion = 1
  4270.  
  4271. UNION ALL
  4272.  
  4273. SELECT
  4274. s.session_id,
  4275. b.top_level_session_id,
  4276. CONVERT(VARCHAR(8000), b.the_path + CONVERT(VARCHAR(8000), s.session_id) + '.') AS the_path
  4277. FROM blockers AS b
  4278. JOIN #sessions AS s ON
  4279. s.blocking_session_id = b.session_id
  4280. AND s.recursion = 1
  4281. AND b.the_path NOT LIKE '%.' + CONVERT(VARCHAR(8000), s.session_id) + '.%' COLLATE Latin1_General_Bin2
  4282. )
  4283. UPDATE s
  4284. SET
  4285. s.blocked_session_count = x.blocked_session_count
  4286. FROM #sessions AS s
  4287. JOIN
  4288. (
  4289. SELECT
  4290. b.top_level_session_id AS session_id,
  4291. COUNT(*) - 1 AS blocked_session_count
  4292. FROM blockers AS b
  4293. GROUP BY
  4294. b.top_level_session_id
  4295. ) x ON
  4296. s.session_id = x.session_id
  4297. WHERE
  4298. s.recursion = 1;
  4299. END;
  4300. IF
  4301. @get_task_info = 2
  4302. AND @output_column_list LIKE '%|[additional_info|]%' ESCAPE '|'
  4303. AND @recursion = 1
  4304. BEGIN;
  4305. CREATE TABLE #blocked_requests
  4306. (
  4307. session_id SMALLINT NOT NULL,
  4308. request_id INT NOT NULL,
  4309. database_name sysname NOT NULL,
  4310. object_id INT,
  4311. hobt_id BIGINT,
  4312. schema_id INT,
  4313. schema_name sysname NULL,
  4314. object_name sysname NULL,
  4315. query_error NVARCHAR(2048),
  4316. PRIMARY KEY (database_name, session_id, request_id)
  4317. );
  4318. CREATE STATISTICS s_database_name ON #blocked_requests (database_name)
  4319. WITH SAMPLE 0 ROWS, NORECOMPUTE;
  4320. CREATE STATISTICS s_schema_name ON #blocked_requests (schema_name)
  4321. WITH SAMPLE 0 ROWS, NORECOMPUTE;
  4322. CREATE STATISTICS s_object_name ON #blocked_requests (object_name)
  4323. WITH SAMPLE 0 ROWS, NORECOMPUTE;
  4324. CREATE STATISTICS s_query_error ON #blocked_requests (query_error)
  4325. WITH SAMPLE 0 ROWS, NORECOMPUTE;
  4326. INSERT #blocked_requests
  4327. (
  4328. session_id,
  4329. request_id,
  4330. database_name,
  4331. object_id,
  4332. hobt_id,
  4333. schema_id
  4334. )
  4335. SELECT
  4336. session_id,
  4337. request_id,
  4338. database_name,
  4339. object_id,
  4340. hobt_id,
  4341. CONVERT(INT, SUBSTRING(schema_node, CHARINDEX(' = ', schema_node) + 3, LEN(schema_node))) AS schema_id
  4342. FROM
  4343. (
  4344. SELECT
  4345. session_id,
  4346. request_id,
  4347. agent_nodes.agent_node.value('(database_name/text())[1]', 'sysname') AS database_name,
  4348. agent_nodes.agent_node.value('(object_id/text())[1]', 'int') AS object_id,
  4349. agent_nodes.agent_node.value('(hobt_id/text())[1]', 'bigint') AS hobt_id,
  4350. agent_nodes.agent_node.value('(metadata_resource/text()[.="SCHEMA"]/../../metadata_class_id/text())[1]', 'varchar(100)') AS schema_node
  4351. FROM #sessions AS s
  4352. CROSS APPLY s.additional_info.nodes('//block_info') AS agent_nodes (agent_node)
  4353. WHERE
  4354. s.recursion = 1
  4355. ) AS t
  4356. WHERE
  4357. t.database_name IS NOT NULL
  4358. AND
  4359. (
  4360. t.object_id IS NOT NULL
  4361. OR t.hobt_id IS NOT NULL
  4362. OR t.schema_node IS NOT NULL
  4363. );
  4364. DECLARE blocks_cursor
  4365. CURSOR LOCAL FAST_FORWARD
  4366. FOR
  4367. SELECT DISTINCT
  4368. database_name
  4369. FROM #blocked_requests;
  4370. OPEN blocks_cursor;
  4371. FETCH NEXT FROM blocks_cursor
  4372. INTO
  4373. @database_name;
  4374. WHILE @@FETCH_STATUS = 0
  4375. BEGIN;
  4376. BEGIN TRY;
  4377. SET @sql_n =
  4378. CONVERT(NVARCHAR(MAX), '') +
  4379. 'UPDATE b ' +
  4380. 'SET ' +
  4381. 'b.schema_name = ' +
  4382. 'REPLACE ' +
  4383. '( ' +
  4384. 'REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( ' +
  4385. 'REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( ' +
  4386. 'REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( ' +
  4387. 's.name COLLATE Latin1_General_Bin2, ' +
  4388. 'NCHAR(31),N''?''),NCHAR(30),N''?''),NCHAR(29),N''?''),NCHAR(28),N''?''),NCHAR(27),N''?''),NCHAR(26),N''?''),NCHAR(25),N''?''),NCHAR(24),N''?''),NCHAR(23),N''?''),NCHAR(22),N''?''), ' +
  4389. 'NCHAR(21),N''?''),NCHAR(20),N''?''),NCHAR(19),N''?''),NCHAR(18),N''?''),NCHAR(17),N''?''),NCHAR(16),N''?''),NCHAR(15),N''?''),NCHAR(14),N''?''),NCHAR(12),N''?''), ' +
  4390. 'NCHAR(11),N''?''),NCHAR(8),N''?''),NCHAR(7),N''?''),NCHAR(6),N''?''),NCHAR(5),N''?''),NCHAR(4),N''?''),NCHAR(3),N''?''),NCHAR(2),N''?''),NCHAR(1),N''?''), ' +
  4391. 'NCHAR(0), ' +
  4392. N''''' ' +
  4393. '), ' +
  4394. 'b.object_name = ' +
  4395. 'REPLACE ' +
  4396. '( ' +
  4397. 'REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( ' +
  4398. 'REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( ' +
  4399. 'REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( ' +
  4400. 'o.name COLLATE Latin1_General_Bin2, ' +
  4401. 'NCHAR(31),N''?''),NCHAR(30),N''?''),NCHAR(29),N''?''),NCHAR(28),N''?''),NCHAR(27),N''?''),NCHAR(26),N''?''),NCHAR(25),N''?''),NCHAR(24),N''?''),NCHAR(23),N''?''),NCHAR(22),N''?''), ' +
  4402. 'NCHAR(21),N''?''),NCHAR(20),N''?''),NCHAR(19),N''?''),NCHAR(18),N''?''),NCHAR(17),N''?''),NCHAR(16),N''?''),NCHAR(15),N''?''),NCHAR(14),N''?''),NCHAR(12),N''?''), ' +
  4403. 'NCHAR(11),N''?''),NCHAR(8),N''?''),NCHAR(7),N''?''),NCHAR(6),N''?''),NCHAR(5),N''?''),NCHAR(4),N''?''),NCHAR(3),N''?''),NCHAR(2),N''?''),NCHAR(1),N''?''), ' +
  4404. 'NCHAR(0), ' +
  4405. N''''' ' +
  4406. ') ' +
  4407. 'FROM #blocked_requests AS b ' +
  4408. 'LEFT OUTER JOIN ' + QUOTENAME(@database_name) + '.sys.partitions AS p ON ' +
  4409. 'p.hobt_id = b.hobt_id ' +
  4410. 'LEFT OUTER JOIN ' + QUOTENAME(@database_name) + '.sys.objects AS o ON ' +
  4411. 'o.object_id = COALESCE(p.object_id, b.object_id) ' +
  4412. 'LEFT OUTER JOIN ' + QUOTENAME(@database_name) + '.sys.schemas AS s ON ' +
  4413. 's.schema_id = COALESCE(o.schema_id, b.schema_id) ' +
  4414. 'WHERE ' +
  4415. 'b.database_name = @database_name; ';
  4416. EXEC sp_executesql
  4417. @sql_n,
  4418. N'@database_name sysname',
  4419. @database_name;
  4420. END TRY
  4421. BEGIN CATCH;
  4422. UPDATE #blocked_requests
  4423. SET
  4424. query_error =
  4425. REPLACE
  4426. (
  4427. REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
  4428. REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
  4429. REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
  4430. CONVERT
  4431. (
  4432. NVARCHAR(MAX),
  4433. ERROR_MESSAGE() COLLATE Latin1_General_Bin2
  4434. ),
  4435. NCHAR(31),N'?'),NCHAR(30),N'?'),NCHAR(29),N'?'),NCHAR(28),N'?'),NCHAR(27),N'?'),NCHAR(26),N'?'),NCHAR(25),N'?'),NCHAR(24),N'?'),NCHAR(23),N'?'),NCHAR(22),N'?'),
  4436. NCHAR(21),N'?'),NCHAR(20),N'?'),NCHAR(19),N'?'),NCHAR(18),N'?'),NCHAR(17),N'?'),NCHAR(16),N'?'),NCHAR(15),N'?'),NCHAR(14),N'?'),NCHAR(12),N'?'),
  4437. NCHAR(11),N'?'),NCHAR(8),N'?'),NCHAR(7),N'?'),NCHAR(6),N'?'),NCHAR(5),N'?'),NCHAR(4),N'?'),NCHAR(3),N'?'),NCHAR(2),N'?'),NCHAR(1),N'?'),
  4438. NCHAR(0),
  4439. N''
  4440. )
  4441. WHERE
  4442. database_name = @database_name;
  4443. END CATCH;
  4444. FETCH NEXT FROM blocks_cursor
  4445. INTO
  4446. @database_name;
  4447. END;
  4448. CLOSE blocks_cursor;
  4449. DEALLOCATE blocks_cursor;
  4450. UPDATE s
  4451. SET
  4452. additional_info.modify
  4453. ('
  4454. insert <schema_name>{sql:column("b.schema_name")}</schema_name>
  4455. as last
  4456. into (/additional_info/block_info)[1]
  4457. ')
  4458. FROM #sessions AS s
  4459. INNER JOIN #blocked_requests AS b ON
  4460. b.session_id = s.session_id
  4461. AND b.request_id = s.request_id
  4462. AND s.recursion = 1
  4463. WHERE
  4464. b.schema_name IS NOT NULL;
  4465. UPDATE s
  4466. SET
  4467. additional_info.modify
  4468. ('
  4469. insert <object_name>{sql:column("b.object_name")}</object_name>
  4470. as last
  4471. into (/additional_info/block_info)[1]
  4472. ')
  4473. FROM #sessions AS s
  4474. INNER JOIN #blocked_requests AS b ON
  4475. b.session_id = s.session_id
  4476. AND b.request_id = s.request_id
  4477. AND s.recursion = 1
  4478. WHERE
  4479. b.object_name IS NOT NULL;
  4480. UPDATE s
  4481. SET
  4482. additional_info.modify
  4483. ('
  4484. insert <query_error>{sql:column("b.query_error")}</query_error>
  4485. as last
  4486. into (/additional_info/block_info)[1]
  4487. ')
  4488. FROM #sessions AS s
  4489. INNER JOIN #blocked_requests AS b ON
  4490. b.session_id = s.session_id
  4491. AND b.request_id = s.request_id
  4492. AND s.recursion = 1
  4493. WHERE
  4494. b.query_error IS NOT NULL;
  4495. END;
  4496. IF
  4497. @output_column_list LIKE '%|[program_name|]%' ESCAPE '|'
  4498. AND @output_column_list LIKE '%|[additional_info|]%' ESCAPE '|'
  4499. AND @recursion = 1
  4500. AND DB_ID('msdb') IS NOT NULL
  4501. BEGIN;
  4502. SET @sql_n =
  4503. N'BEGIN TRY;
  4504. DECLARE @job_name sysname;
  4505. SET @job_name = NULL;
  4506. DECLARE @step_name sysname;
  4507. SET @step_name = NULL;
  4508. SELECT
  4509. @job_name =
  4510. REPLACE
  4511. (
  4512. REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
  4513. REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
  4514. REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
  4515. j.name,
  4516. NCHAR(31),N''?''),NCHAR(30),N''?''),NCHAR(29),N''?''),NCHAR(28),N''?''),NCHAR(27),N''?''),NCHAR(26),N''?''),NCHAR(25),N''?''),NCHAR(24),N''?''),NCHAR(23),N''?''),NCHAR(22),N''?''),
  4517. NCHAR(21),N''?''),NCHAR(20),N''?''),NCHAR(19),N''?''),NCHAR(18),N''?''),NCHAR(17),N''?''),NCHAR(16),N''?''),NCHAR(15),N''?''),NCHAR(14),N''?''),NCHAR(12),N''?''),
  4518. NCHAR(11),N''?''),NCHAR(8),N''?''),NCHAR(7),N''?''),NCHAR(6),N''?''),NCHAR(5),N''?''),NCHAR(4),N''?''),NCHAR(3),N''?''),NCHAR(2),N''?''),NCHAR(1),N''?''),
  4519. NCHAR(0),
  4520. N''?''
  4521. ),
  4522. @step_name =
  4523. REPLACE
  4524. (
  4525. REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
  4526. REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
  4527. REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
  4528. s.step_name,
  4529. NCHAR(31),N''?''),NCHAR(30),N''?''),NCHAR(29),N''?''),NCHAR(28),N''?''),NCHAR(27),N''?''),NCHAR(26),N''?''),NCHAR(25),N''?''),NCHAR(24),N''?''),NCHAR(23),N''?''),NCHAR(22),N''?''),
  4530. NCHAR(21),N''?''),NCHAR(20),N''?''),NCHAR(19),N''?''),NCHAR(18),N''?''),NCHAR(17),N''?''),NCHAR(16),N''?''),NCHAR(15),N''?''),NCHAR(14),N''?''),NCHAR(12),N''?''),
  4531. NCHAR(11),N''?''),NCHAR(8),N''?''),NCHAR(7),N''?''),NCHAR(6),N''?''),NCHAR(5),N''?''),NCHAR(4),N''?''),NCHAR(3),N''?''),NCHAR(2),N''?''),NCHAR(1),N''?''),
  4532. NCHAR(0),
  4533. N''?''
  4534. )
  4535. FROM msdb.dbo.sysjobs AS j
  4536. INNER JOIN msdb.dbo.sysjobsteps AS s ON
  4537. j.job_id = s.job_id
  4538. WHERE
  4539. j.job_id = @job_id
  4540. AND s.step_id = @step_id;
  4541. IF @job_name IS NOT NULL
  4542. BEGIN;
  4543. UPDATE s
  4544. SET
  4545. additional_info.modify
  4546. (''
  4547. insert text{sql:variable("@job_name")}
  4548. into (/additional_info/agent_job_info/job_name)[1]
  4549. '')
  4550. FROM #sessions AS s
  4551. WHERE
  4552. s.session_id = @session_id
  4553. AND s.recursion = 1
  4554. OPTION (KEEPFIXED PLAN);
  4555. UPDATE s
  4556. SET
  4557. additional_info.modify
  4558. (''
  4559. insert text{sql:variable("@step_name")}
  4560. into (/additional_info/agent_job_info/step_name)[1]
  4561. '')
  4562. FROM #sessions AS s
  4563. WHERE
  4564. s.session_id = @session_id
  4565. AND s.recursion = 1
  4566. OPTION (KEEPFIXED PLAN);
  4567. END;
  4568. END TRY
  4569. BEGIN CATCH;
  4570. DECLARE @msdb_error_message NVARCHAR(256);
  4571. SET @msdb_error_message = ERROR_MESSAGE();
  4572. UPDATE s
  4573. SET
  4574. additional_info.modify
  4575. (''
  4576. insert <msdb_query_error>{sql:variable("@msdb_error_message")}</msdb_query_error>
  4577. as last
  4578. into (/additional_info/agent_job_info)[1]
  4579. '')
  4580. FROM #sessions AS s
  4581. WHERE
  4582. s.session_id = @session_id
  4583. AND s.recursion = 1
  4584. OPTION (KEEPFIXED PLAN);
  4585. END CATCH;'
  4586.  
  4587. DECLARE @job_id UNIQUEIDENTIFIER;
  4588. DECLARE @step_id INT;
  4589. DECLARE agent_cursor
  4590. CURSOR LOCAL FAST_FORWARD
  4591. FOR
  4592. SELECT
  4593. s.session_id,
  4594. agent_nodes.agent_node.value('(job_id/text())[1]', 'uniqueidentifier') AS job_id,
  4595. agent_nodes.agent_node.value('(step_id/text())[1]', 'int') AS step_id
  4596. FROM #sessions AS s
  4597. CROSS APPLY s.additional_info.nodes('//agent_job_info') AS agent_nodes (agent_node)
  4598. WHERE
  4599. s.recursion = 1
  4600. OPTION (KEEPFIXED PLAN);
  4601. OPEN agent_cursor;
  4602. FETCH NEXT FROM agent_cursor
  4603. INTO
  4604. @session_id,
  4605. @job_id,
  4606. @step_id;
  4607. WHILE @@FETCH_STATUS = 0
  4608. BEGIN;
  4609. EXEC sp_executesql
  4610. @sql_n,
  4611. N'@job_id UNIQUEIDENTIFIER, @step_id INT, @session_id SMALLINT',
  4612. @job_id, @step_id, @session_id
  4613.  
  4614. FETCH NEXT FROM agent_cursor
  4615. INTO
  4616. @session_id,
  4617. @job_id,
  4618. @step_id;
  4619. END;
  4620. CLOSE agent_cursor;
  4621. DEALLOCATE agent_cursor;
  4622. END;
  4623. IF
  4624. @delta_interval > 0
  4625. AND @recursion <> 1
  4626. BEGIN;
  4627. SET @recursion = 1;
  4628. DECLARE @delay_time CHAR(12);
  4629. SET @delay_time = CONVERT(VARCHAR, DATEADD(second, @delta_interval, 0), 114);
  4630. WAITFOR DELAY @delay_time;
  4631. GOTO REDO;
  4632. END;
  4633. END;
  4634. SET @sql =
  4635. --Outer column list
  4636. CONVERT
  4637. (
  4638. VARCHAR(MAX),
  4639. CASE
  4640. WHEN
  4641. @destination_table <> ''
  4642. AND @return_schema = 0
  4643. THEN 'INSERT ' + @destination_table + ' '
  4644. ELSE ''
  4645. END +
  4646. 'SELECT ' +
  4647. @output_column_list + ' ' +
  4648. CASE @return_schema
  4649. WHEN 1 THEN 'INTO #session_schema '
  4650. ELSE ''
  4651. END
  4652. --End outer column list
  4653. ) +
  4654. --Inner column list
  4655. CONVERT
  4656. (
  4657. VARCHAR(MAX),
  4658. 'FROM ' +
  4659. '( ' +
  4660. 'SELECT ' +
  4661. 'session_id, ' +
  4662. --[dd hh:mm:ss.mss]
  4663. CASE
  4664. WHEN @format_output IN (1, 2) THEN
  4665. 'CASE ' +
  4666. 'WHEN elapsed_time < 0 THEN ' +
  4667. 'RIGHT ' +
  4668. '( ' +
  4669. 'REPLICATE(''0'', max_elapsed_length) + CONVERT(VARCHAR, (-1 * elapsed_time) / 86400), ' +
  4670. 'max_elapsed_length ' +
  4671. ') + ' +
  4672. 'RIGHT ' +
  4673. '( ' +
  4674. 'CONVERT(VARCHAR, DATEADD(second, (-1 * elapsed_time), 0), 120), ' +
  4675. '9 ' +
  4676. ') + ' +
  4677. '''.000'' ' +
  4678. 'ELSE ' +
  4679. 'RIGHT ' +
  4680. '( ' +
  4681. 'REPLICATE(''0'', max_elapsed_length) + CONVERT(VARCHAR, elapsed_time / 86400000), ' +
  4682. 'max_elapsed_length ' +
  4683. ') + ' +
  4684. 'RIGHT ' +
  4685. '( ' +
  4686. 'CONVERT(VARCHAR, DATEADD(second, elapsed_time / 1000, 0), 120), ' +
  4687. '9 ' +
  4688. ') + ' +
  4689. '''.'' + ' +
  4690. 'RIGHT(''000'' + CONVERT(VARCHAR, elapsed_time % 1000), 3) ' +
  4691. 'END AS [dd hh:mm:ss.mss], '
  4692. ELSE
  4693. ''
  4694. END +
  4695. --[dd hh:mm:ss.mss (avg)] / avg_elapsed_time
  4696. CASE
  4697. WHEN @format_output IN (1, 2) THEN
  4698. 'RIGHT ' +
  4699. '( ' +
  4700. '''00'' + CONVERT(VARCHAR, avg_elapsed_time / 86400000), ' +
  4701. '2 ' +
  4702. ') + ' +
  4703. 'RIGHT ' +
  4704. '( ' +
  4705. 'CONVERT(VARCHAR, DATEADD(second, avg_elapsed_time / 1000, 0), 120), ' +
  4706. '9 ' +
  4707. ') + ' +
  4708. '''.'' + ' +
  4709. 'RIGHT(''000'' + CONVERT(VARCHAR, avg_elapsed_time % 1000), 3) AS [dd hh:mm:ss.mss (avg)], '
  4710. ELSE
  4711. 'avg_elapsed_time, '
  4712. END +
  4713. --physical_io
  4714. CASE @format_output
  4715. WHEN 1 THEN 'CONVERT(VARCHAR, SPACE(MAX(LEN(CONVERT(VARCHAR, physical_io))) OVER() - LEN(CONVERT(VARCHAR, physical_io))) + LEFT(CONVERT(CHAR(22), CONVERT(MONEY, physical_io), 1), 19)) AS '
  4716. WHEN 2 THEN 'CONVERT(VARCHAR, LEFT(CONVERT(CHAR(22), CONVERT(MONEY, physical_io), 1), 19)) AS '
  4717. ELSE ''
  4718. END + 'physical_io, ' +
  4719. --reads
  4720. CASE @format_output
  4721. WHEN 1 THEN 'CONVERT(VARCHAR, SPACE(MAX(LEN(CONVERT(VARCHAR, reads))) OVER() - LEN(CONVERT(VARCHAR, reads))) + LEFT(CONVERT(CHAR(22), CONVERT(MONEY, reads), 1), 19)) AS '
  4722. WHEN 2 THEN 'CONVERT(VARCHAR, LEFT(CONVERT(CHAR(22), CONVERT(MONEY, reads), 1), 19)) AS '
  4723. ELSE ''
  4724. END + 'reads, ' +
  4725. --physical_reads
  4726. CASE @format_output
  4727. WHEN 1 THEN 'CONVERT(VARCHAR, SPACE(MAX(LEN(CONVERT(VARCHAR, physical_reads))) OVER() - LEN(CONVERT(VARCHAR, physical_reads))) + LEFT(CONVERT(CHAR(22), CONVERT(MONEY, physical_reads), 1), 19)) AS '
  4728. WHEN 2 THEN 'CONVERT(VARCHAR, LEFT(CONVERT(CHAR(22), CONVERT(MONEY, physical_reads), 1), 19)) AS '
  4729. ELSE ''
  4730. END + 'physical_reads, ' +
  4731. --writes
  4732. CASE @format_output
  4733. WHEN 1 THEN 'CONVERT(VARCHAR, SPACE(MAX(LEN(CONVERT(VARCHAR, writes))) OVER() - LEN(CONVERT(VARCHAR, writes))) + LEFT(CONVERT(CHAR(22), CONVERT(MONEY, writes), 1), 19)) AS '
  4734. WHEN 2 THEN 'CONVERT(VARCHAR, LEFT(CONVERT(CHAR(22), CONVERT(MONEY, writes), 1), 19)) AS '
  4735. ELSE ''
  4736. END + 'writes, ' +
  4737. --tempdb_allocations
  4738. CASE @format_output
  4739. WHEN 1 THEN 'CONVERT(VARCHAR, SPACE(MAX(LEN(CONVERT(VARCHAR, tempdb_allocations))) OVER() - LEN(CONVERT(VARCHAR, tempdb_allocations))) + LEFT(CONVERT(CHAR(22), CONVERT(MONEY, tempdb_allocations), 1), 19)) AS '
  4740. WHEN 2 THEN 'CONVERT(VARCHAR, LEFT(CONVERT(CHAR(22), CONVERT(MONEY, tempdb_allocations), 1), 19)) AS '
  4741. ELSE ''
  4742. END + 'tempdb_allocations, ' +
  4743. --tempdb_current
  4744. CASE @format_output
  4745. WHEN 1 THEN 'CONVERT(VARCHAR, SPACE(MAX(LEN(CONVERT(VARCHAR, tempdb_current))) OVER() - LEN(CONVERT(VARCHAR, tempdb_current))) + LEFT(CONVERT(CHAR(22), CONVERT(MONEY, tempdb_current), 1), 19)) AS '
  4746. WHEN 2 THEN 'CONVERT(VARCHAR, LEFT(CONVERT(CHAR(22), CONVERT(MONEY, tempdb_current), 1), 19)) AS '
  4747. ELSE ''
  4748. END + 'tempdb_current, ' +
  4749. --CPU
  4750. CASE @format_output
  4751. WHEN 1 THEN 'CONVERT(VARCHAR, SPACE(MAX(LEN(CONVERT(VARCHAR, CPU))) OVER() - LEN(CONVERT(VARCHAR, CPU))) + LEFT(CONVERT(CHAR(22), CONVERT(MONEY, CPU), 1), 19)) AS '
  4752. WHEN 2 THEN 'CONVERT(VARCHAR, LEFT(CONVERT(CHAR(22), CONVERT(MONEY, CPU), 1), 19)) AS '
  4753. ELSE ''
  4754. END + 'CPU, ' +
  4755. --context_switches
  4756. CASE @format_output
  4757. WHEN 1 THEN 'CONVERT(VARCHAR, SPACE(MAX(LEN(CONVERT(VARCHAR, context_switches))) OVER() - LEN(CONVERT(VARCHAR, context_switches))) + LEFT(CONVERT(CHAR(22), CONVERT(MONEY, context_switches), 1), 19)) AS '
  4758. WHEN 2 THEN 'CONVERT(VARCHAR, LEFT(CONVERT(CHAR(22), CONVERT(MONEY, context_switches), 1), 19)) AS '
  4759. ELSE ''
  4760. END + 'context_switches, ' +
  4761. --used_memory
  4762. CASE @format_output
  4763. WHEN 1 THEN 'CONVERT(VARCHAR, SPACE(MAX(LEN(CONVERT(VARCHAR, used_memory))) OVER() - LEN(CONVERT(VARCHAR, used_memory))) + LEFT(CONVERT(CHAR(22), CONVERT(MONEY, used_memory), 1), 19)) AS '
  4764. WHEN 2 THEN 'CONVERT(VARCHAR, LEFT(CONVERT(CHAR(22), CONVERT(MONEY, used_memory), 1), 19)) AS '
  4765. ELSE ''
  4766. END + 'used_memory, ' +
  4767. CASE
  4768. WHEN @output_column_list LIKE '%|_delta|]%' ESCAPE '|' THEN
  4769. --physical_io_delta
  4770. 'CASE ' +
  4771. 'WHEN ' +
  4772. 'first_request_start_time = last_request_start_time ' +
  4773. 'AND num_events = 2 ' +
  4774. 'AND physical_io_delta >= 0 ' +
  4775. 'THEN ' +
  4776. CASE @format_output
  4777. WHEN 1 THEN 'CONVERT(VARCHAR, SPACE(MAX(LEN(CONVERT(VARCHAR, physical_io_delta))) OVER() - LEN(CONVERT(VARCHAR, physical_io_delta))) + LEFT(CONVERT(CHAR(22), CONVERT(MONEY, physical_io_delta), 1), 19)) '
  4778. WHEN 2 THEN 'CONVERT(VARCHAR, LEFT(CONVERT(CHAR(22), CONVERT(MONEY, physical_io_delta), 1), 19)) '
  4779. ELSE 'physical_io_delta '
  4780. END +
  4781. 'ELSE NULL ' +
  4782. 'END AS physical_io_delta, ' +
  4783. --reads_delta
  4784. 'CASE ' +
  4785. 'WHEN ' +
  4786. 'first_request_start_time = last_request_start_time ' +
  4787. 'AND num_events = 2 ' +
  4788. 'AND reads_delta >= 0 ' +
  4789. 'THEN ' +
  4790. CASE @format_output
  4791. WHEN 1 THEN 'CONVERT(VARCHAR, SPACE(MAX(LEN(CONVERT(VARCHAR, reads_delta))) OVER() - LEN(CONVERT(VARCHAR, reads_delta))) + LEFT(CONVERT(CHAR(22), CONVERT(MONEY, reads_delta), 1), 19)) '
  4792. WHEN 2 THEN 'CONVERT(VARCHAR, LEFT(CONVERT(CHAR(22), CONVERT(MONEY, reads_delta), 1), 19)) '
  4793. ELSE 'reads_delta '
  4794. END +
  4795. 'ELSE NULL ' +
  4796. 'END AS reads_delta, ' +
  4797. --physical_reads_delta
  4798. 'CASE ' +
  4799. 'WHEN ' +
  4800. 'first_request_start_time = last_request_start_time ' +
  4801. 'AND num_events = 2 ' +
  4802. 'AND physical_reads_delta >= 0 ' +
  4803. 'THEN ' +
  4804. CASE @format_output
  4805. WHEN 1 THEN 'CONVERT(VARCHAR, SPACE(MAX(LEN(CONVERT(VARCHAR, physical_reads_delta))) OVER() - LEN(CONVERT(VARCHAR, physical_reads_delta))) + LEFT(CONVERT(CHAR(22), CONVERT(MONEY, physical_reads_delta), 1), 19)) '
  4806. WHEN 2 THEN 'CONVERT(VARCHAR, LEFT(CONVERT(CHAR(22), CONVERT(MONEY, physical_reads_delta), 1), 19)) '
  4807. ELSE 'physical_reads_delta '
  4808. END +
  4809. 'ELSE NULL ' +
  4810. 'END AS physical_reads_delta, ' +
  4811. --writes_delta
  4812. 'CASE ' +
  4813. 'WHEN ' +
  4814. 'first_request_start_time = last_request_start_time ' +
  4815. 'AND num_events = 2 ' +
  4816. 'AND writes_delta >= 0 ' +
  4817. 'THEN ' +
  4818. CASE @format_output
  4819. WHEN 1 THEN 'CONVERT(VARCHAR, SPACE(MAX(LEN(CONVERT(VARCHAR, writes_delta))) OVER() - LEN(CONVERT(VARCHAR, writes_delta))) + LEFT(CONVERT(CHAR(22), CONVERT(MONEY, writes_delta), 1), 19)) '
  4820. WHEN 2 THEN 'CONVERT(VARCHAR, LEFT(CONVERT(CHAR(22), CONVERT(MONEY, writes_delta), 1), 19)) '
  4821. ELSE 'writes_delta '
  4822. END +
  4823. 'ELSE NULL ' +
  4824. 'END AS writes_delta, ' +
  4825. --tempdb_allocations_delta
  4826. 'CASE ' +
  4827. 'WHEN ' +
  4828. 'first_request_start_time = last_request_start_time ' +
  4829. 'AND num_events = 2 ' +
  4830. 'AND tempdb_allocations_delta >= 0 ' +
  4831. 'THEN ' +
  4832. CASE @format_output
  4833. WHEN 1 THEN 'CONVERT(VARCHAR, SPACE(MAX(LEN(CONVERT(VARCHAR, tempdb_allocations_delta))) OVER() - LEN(CONVERT(VARCHAR, tempdb_allocations_delta))) + LEFT(CONVERT(CHAR(22), CONVERT(MONEY, tempdb_allocations_delta), 1), 19)) '
  4834. WHEN 2 THEN 'CONVERT(VARCHAR, LEFT(CONVERT(CHAR(22), CONVERT(MONEY, tempdb_allocations_delta), 1), 19)) '
  4835. ELSE 'tempdb_allocations_delta '
  4836. END +
  4837. 'ELSE NULL ' +
  4838. 'END AS tempdb_allocations_delta, ' +
  4839. --tempdb_current_delta
  4840. --this is the only one that can (legitimately) go negative
  4841. 'CASE ' +
  4842. 'WHEN ' +
  4843. 'first_request_start_time = last_request_start_time ' +
  4844. 'AND num_events = 2 ' +
  4845. 'THEN ' +
  4846. CASE @format_output
  4847. WHEN 1 THEN 'CONVERT(VARCHAR, SPACE(MAX(LEN(CONVERT(VARCHAR, tempdb_current_delta))) OVER() - LEN(CONVERT(VARCHAR, tempdb_current_delta))) + LEFT(CONVERT(CHAR(22), CONVERT(MONEY, tempdb_current_delta), 1), 19)) '
  4848. WHEN 2 THEN 'CONVERT(VARCHAR, LEFT(CONVERT(CHAR(22), CONVERT(MONEY, tempdb_current_delta), 1), 19)) '
  4849. ELSE 'tempdb_current_delta '
  4850. END +
  4851. 'ELSE NULL ' +
  4852. 'END AS tempdb_current_delta, ' +
  4853. --CPU_delta
  4854. 'CASE ' +
  4855. 'WHEN ' +
  4856. 'first_request_start_time = last_request_start_time ' +
  4857. 'AND num_events = 2 ' +
  4858. 'THEN ' +
  4859. 'CASE ' +
  4860. 'WHEN ' +
  4861. 'thread_CPU_delta > CPU_delta ' +
  4862. 'AND thread_CPU_delta > 0 ' +
  4863. 'THEN ' +
  4864. CASE @format_output
  4865. WHEN 1 THEN 'CONVERT(VARCHAR, SPACE(MAX(LEN(CONVERT(VARCHAR, thread_CPU_delta + CPU_delta))) OVER() - LEN(CONVERT(VARCHAR, thread_CPU_delta))) + LEFT(CONVERT(CHAR(22), CONVERT(MONEY, thread_CPU_delta), 1), 19)) '
  4866. WHEN 2 THEN 'CONVERT(VARCHAR, LEFT(CONVERT(CHAR(22), CONVERT(MONEY, thread_CPU_delta), 1), 19)) '
  4867. ELSE 'thread_CPU_delta '
  4868. END +
  4869. 'WHEN CPU_delta >= 0 THEN ' +
  4870. CASE @format_output
  4871. WHEN 1 THEN 'CONVERT(VARCHAR, SPACE(MAX(LEN(CONVERT(VARCHAR, thread_CPU_delta + CPU_delta))) OVER() - LEN(CONVERT(VARCHAR, CPU_delta))) + LEFT(CONVERT(CHAR(22), CONVERT(MONEY, CPU_delta), 1), 19)) '
  4872. WHEN 2 THEN 'CONVERT(VARCHAR, LEFT(CONVERT(CHAR(22), CONVERT(MONEY, CPU_delta), 1), 19)) '
  4873. ELSE 'CPU_delta '
  4874. END +
  4875. 'ELSE NULL ' +
  4876. 'END ' +
  4877. 'ELSE ' +
  4878. 'NULL ' +
  4879. 'END AS CPU_delta, ' +
  4880. --context_switches_delta
  4881. 'CASE ' +
  4882. 'WHEN ' +
  4883. 'first_request_start_time = last_request_start_time ' +
  4884. 'AND num_events = 2 ' +
  4885. 'AND context_switches_delta >= 0 ' +
  4886. 'THEN ' +
  4887. CASE @format_output
  4888. WHEN 1 THEN 'CONVERT(VARCHAR, SPACE(MAX(LEN(CONVERT(VARCHAR, context_switches_delta))) OVER() - LEN(CONVERT(VARCHAR, context_switches_delta))) + LEFT(CONVERT(CHAR(22), CONVERT(MONEY, context_switches_delta), 1), 19)) '
  4889. WHEN 2 THEN 'CONVERT(VARCHAR, LEFT(CONVERT(CHAR(22), CONVERT(MONEY, context_switches_delta), 1), 19)) '
  4890. ELSE 'context_switches_delta '
  4891. END +
  4892. 'ELSE NULL ' +
  4893. 'END AS context_switches_delta, ' +
  4894. --used_memory_delta
  4895. 'CASE ' +
  4896. 'WHEN ' +
  4897. 'first_request_start_time = last_request_start_time ' +
  4898. 'AND num_events = 2 ' +
  4899. 'AND used_memory_delta >= 0 ' +
  4900. 'THEN ' +
  4901. CASE @format_output
  4902. WHEN 1 THEN 'CONVERT(VARCHAR, SPACE(MAX(LEN(CONVERT(VARCHAR, used_memory_delta))) OVER() - LEN(CONVERT(VARCHAR, used_memory_delta))) + LEFT(CONVERT(CHAR(22), CONVERT(MONEY, used_memory_delta), 1), 19)) '
  4903. WHEN 2 THEN 'CONVERT(VARCHAR, LEFT(CONVERT(CHAR(22), CONVERT(MONEY, used_memory_delta), 1), 19)) '
  4904. ELSE 'used_memory_delta '
  4905. END +
  4906. 'ELSE NULL ' +
  4907. 'END AS used_memory_delta, '
  4908. ELSE ''
  4909. END +
  4910. --tasks
  4911. CASE @format_output
  4912. WHEN 1 THEN 'CONVERT(VARCHAR, SPACE(MAX(LEN(CONVERT(VARCHAR, tasks))) OVER() - LEN(CONVERT(VARCHAR, tasks))) + LEFT(CONVERT(CHAR(22), CONVERT(MONEY, tasks), 1), 19)) AS '
  4913. WHEN 2 THEN 'CONVERT(VARCHAR, LEFT(CONVERT(CHAR(22), CONVERT(MONEY, tasks), 1), 19)) '
  4914. ELSE ''
  4915. END + 'tasks, ' +
  4916. 'status, ' +
  4917. 'wait_info, ' +
  4918. 'locks, ' +
  4919. 'tran_start_time, ' +
  4920. 'LEFT(tran_log_writes, LEN(tran_log_writes) - 1) AS tran_log_writes, ' +
  4921. --open_tran_count
  4922. CASE @format_output
  4923. WHEN 1 THEN 'CONVERT(VARCHAR, SPACE(MAX(LEN(CONVERT(VARCHAR, open_tran_count))) OVER() - LEN(CONVERT(VARCHAR, open_tran_count))) + LEFT(CONVERT(CHAR(22), CONVERT(MONEY, open_tran_count), 1), 19)) AS '
  4924. WHEN 2 THEN 'CONVERT(VARCHAR, LEFT(CONVERT(CHAR(22), CONVERT(MONEY, open_tran_count), 1), 19)) AS '
  4925. ELSE ''
  4926. END + 'open_tran_count, ' +
  4927. --sql_command
  4928. CASE @format_output
  4929. WHEN 0 THEN 'REPLACE(REPLACE(CONVERT(NVARCHAR(MAX), sql_command), ''<?query --''+CHAR(13)+CHAR(10), ''''), CHAR(13)+CHAR(10)+''--?>'', '''') AS '
  4930. ELSE ''
  4931. END + 'sql_command, ' +
  4932. --sql_text
  4933. CASE @format_output
  4934. WHEN 0 THEN 'REPLACE(REPLACE(CONVERT(NVARCHAR(MAX), sql_text), ''<?query --''+CHAR(13)+CHAR(10), ''''), CHAR(13)+CHAR(10)+''--?>'', '''') AS '
  4935. ELSE ''
  4936. END + 'sql_text, ' +
  4937. 'query_plan, ' +
  4938. 'blocking_session_id, ' +
  4939. --blocked_session_count
  4940. CASE @format_output
  4941. WHEN 1 THEN 'CONVERT(VARCHAR, SPACE(MAX(LEN(CONVERT(VARCHAR, blocked_session_count))) OVER() - LEN(CONVERT(VARCHAR, blocked_session_count))) + LEFT(CONVERT(CHAR(22), CONVERT(MONEY, blocked_session_count), 1), 19)) AS '
  4942. WHEN 2 THEN 'CONVERT(VARCHAR, LEFT(CONVERT(CHAR(22), CONVERT(MONEY, blocked_session_count), 1), 19)) AS '
  4943. ELSE ''
  4944. END + 'blocked_session_count, ' +
  4945. --percent_complete
  4946. CASE @format_output
  4947. WHEN 1 THEN 'CONVERT(VARCHAR, SPACE(MAX(LEN(CONVERT(VARCHAR, CONVERT(MONEY, percent_complete), 2))) OVER() - LEN(CONVERT(VARCHAR, CONVERT(MONEY, percent_complete), 2))) + CONVERT(CHAR(22), CONVERT(MONEY, percent_complete), 2)) AS '
  4948. WHEN 2 THEN 'CONVERT(VARCHAR, CONVERT(CHAR(22), CONVERT(MONEY, percent_complete), 1)) AS '
  4949. ELSE ''
  4950. END + 'percent_complete, ' +
  4951. 'host_name, ' +
  4952. 'login_name, ' +
  4953. 'database_name, ' +
  4954. 'program_name, ' +
  4955. 'additional_info, ' +
  4956. 'start_time, ' +
  4957. 'login_time, ' +
  4958. 'CASE ' +
  4959. 'WHEN status = N''sleeping'' THEN NULL ' +
  4960. 'ELSE request_id ' +
  4961. 'END AS request_id, ' +
  4962. 'GETDATE() AS collection_time '
  4963. --End inner column list
  4964. ) +
  4965. --Derived table and INSERT specification
  4966. CONVERT
  4967. (
  4968. VARCHAR(MAX),
  4969. 'FROM ' +
  4970. '( ' +
  4971. 'SELECT TOP(2147483647) ' +
  4972. '*, ' +
  4973. 'CASE ' +
  4974. 'MAX ' +
  4975. '( ' +
  4976. 'LEN ' +
  4977. '( ' +
  4978. 'CONVERT ' +
  4979. '( ' +
  4980. 'VARCHAR, ' +
  4981. 'CASE ' +
  4982. 'WHEN elapsed_time < 0 THEN ' +
  4983. '(-1 * elapsed_time) / 86400 ' +
  4984. 'ELSE ' +
  4985. 'elapsed_time / 86400000 ' +
  4986. 'END ' +
  4987. ') ' +
  4988. ') ' +
  4989. ') OVER () ' +
  4990. 'WHEN 1 THEN 2 ' +
  4991. 'ELSE ' +
  4992. 'MAX ' +
  4993. '( ' +
  4994. 'LEN ' +
  4995. '( ' +
  4996. 'CONVERT ' +
  4997. '( ' +
  4998. 'VARCHAR, ' +
  4999. 'CASE ' +
  5000. 'WHEN elapsed_time < 0 THEN ' +
  5001. '(-1 * elapsed_time) / 86400 ' +
  5002. 'ELSE ' +
  5003. 'elapsed_time / 86400000 ' +
  5004. 'END ' +
  5005. ') ' +
  5006. ') ' +
  5007. ') OVER () ' +
  5008. 'END AS max_elapsed_length, ' +
  5009. CASE
  5010. WHEN @output_column_list LIKE '%|_delta|]%' ESCAPE '|' THEN
  5011. 'MAX(physical_io * recursion) OVER (PARTITION BY session_id, request_id) + ' +
  5012. 'MIN(physical_io * recursion) OVER (PARTITION BY session_id, request_id) AS physical_io_delta, ' +
  5013. 'MAX(reads * recursion) OVER (PARTITION BY session_id, request_id) + ' +
  5014. 'MIN(reads * recursion) OVER (PARTITION BY session_id, request_id) AS reads_delta, ' +
  5015. 'MAX(physical_reads * recursion) OVER (PARTITION BY session_id, request_id) + ' +
  5016. 'MIN(physical_reads * recursion) OVER (PARTITION BY session_id, request_id) AS physical_reads_delta, ' +
  5017. 'MAX(writes * recursion) OVER (PARTITION BY session_id, request_id) + ' +
  5018. 'MIN(writes * recursion) OVER (PARTITION BY session_id, request_id) AS writes_delta, ' +
  5019. 'MAX(tempdb_allocations * recursion) OVER (PARTITION BY session_id, request_id) + ' +
  5020. 'MIN(tempdb_allocations * recursion) OVER (PARTITION BY session_id, request_id) AS tempdb_allocations_delta, ' +
  5021. 'MAX(tempdb_current * recursion) OVER (PARTITION BY session_id, request_id) + ' +
  5022. 'MIN(tempdb_current * recursion) OVER (PARTITION BY session_id, request_id) AS tempdb_current_delta, ' +
  5023. 'MAX(CPU * recursion) OVER (PARTITION BY session_id, request_id) + ' +
  5024. 'MIN(CPU * recursion) OVER (PARTITION BY session_id, request_id) AS CPU_delta, ' +
  5025. 'MAX(thread_CPU_snapshot * recursion) OVER (PARTITION BY session_id, request_id) + ' +
  5026. 'MIN(thread_CPU_snapshot * recursion) OVER (PARTITION BY session_id, request_id) AS thread_CPU_delta, ' +
  5027. 'MAX(context_switches * recursion) OVER (PARTITION BY session_id, request_id) + ' +
  5028. 'MIN(context_switches * recursion) OVER (PARTITION BY session_id, request_id) AS context_switches_delta, ' +
  5029. 'MAX(used_memory * recursion) OVER (PARTITION BY session_id, request_id) + ' +
  5030. 'MIN(used_memory * recursion) OVER (PARTITION BY session_id, request_id) AS used_memory_delta, ' +
  5031. 'MIN(last_request_start_time) OVER (PARTITION BY session_id, request_id) AS first_request_start_time, '
  5032. ELSE ''
  5033. END +
  5034. 'COUNT(*) OVER (PARTITION BY session_id, request_id) AS num_events ' +
  5035. 'FROM #sessions AS s1 ' +
  5036. CASE
  5037. WHEN @sort_order = '' THEN ''
  5038. ELSE
  5039. 'ORDER BY ' +
  5040. @sort_order
  5041. END +
  5042. ') AS s ' +
  5043. 'WHERE ' +
  5044. 's.recursion = 1 ' +
  5045. ') x ' +
  5046. 'OPTION (KEEPFIXED PLAN); ' +
  5047. '' +
  5048. CASE @return_schema
  5049. WHEN 1 THEN
  5050. 'SET @schema = ' +
  5051. '''CREATE TABLE <table_name> ( '' + ' +
  5052. 'STUFF ' +
  5053. '( ' +
  5054. '( ' +
  5055. 'SELECT ' +
  5056. ''','' + ' +
  5057. 'QUOTENAME(COLUMN_NAME) + '' '' + ' +
  5058. 'DATA_TYPE + ' +
  5059. 'CASE ' +
  5060. 'WHEN DATA_TYPE LIKE ''%char'' THEN ''('' + COALESCE(NULLIF(CONVERT(VARCHAR, CHARACTER_MAXIMUM_LENGTH), ''-1''), ''max'') + '') '' ' +
  5061. 'ELSE '' '' ' +
  5062. 'END + ' +
  5063. 'CASE IS_NULLABLE ' +
  5064. 'WHEN ''NO'' THEN ''NOT '' ' +
  5065. 'ELSE '''' ' +
  5066. 'END + ''NULL'' AS [text()] ' +
  5067. 'FROM tempdb.INFORMATION_SCHEMA.COLUMNS ' +
  5068. 'WHERE ' +
  5069. 'TABLE_NAME = (SELECT name FROM tempdb.sys.objects WHERE object_id = OBJECT_ID(''tempdb..#session_schema'')) ' +
  5070. 'ORDER BY ' +
  5071. 'ORDINAL_POSITION ' +
  5072. 'FOR XML ' +
  5073. 'PATH('''') ' +
  5074. '), + ' +
  5075. '1, ' +
  5076. '1, ' +
  5077. ''''' ' +
  5078. ') + ' +
  5079. ''')''; '
  5080. ELSE ''
  5081. END
  5082. --End derived table and INSERT specification
  5083. );
  5084. SET @sql_n = CONVERT(NVARCHAR(MAX), @sql);
  5085. EXEC sp_executesql
  5086. @sql_n,
  5087. N'@schema VARCHAR(MAX) OUTPUT',
  5088. @schema OUTPUT;
  5089. END;
  5090. GO

执行存储过程,结果输出如下:

3.指定特殊参数 

此外,我们可以通过指定参数获取更多的运行信息

3.1 @find_block_leaders

可以将@find_block_leaders参数的值设置为1,然后对blocked_session_count列的结果进行排序,以检查潜在客户阻止程序和被阻止的会话。

  1. EXEC sp_WhoIsActive
  2. @find_block_leaders = 1,
  3. @sort_order = '[blocked_session_count] DESC'

在输出结果中,我们看到session-id 58是线索阻止程序,它阻止了输出表中下面列出的2个会话。

 

 3.2 @get_plans

 指定参数@ get_plans = 1,能得到它的执行计划,输出中包含带有XML执行计划的附加列。

  1. EXEC sp_WhoIsActive @get_plans = 1;

 

 

 单击查询计划,您可以看到查询执行计划。

 

 3.3 @get_locks

使用此参数获取XML代码段,以获取有关在SQL Server会话中持有的锁的详细信息

 

 3.4 @get_additional_info

通过@get_additional_info 参数可以查看 可能性能性能的several session parameters

  1. EXEC sp_WhoIsActive
  2. @get_additional_info = 1

 

四. 参考:

1.https://github.com/amachanic/sp_whoisactive/releases

2.https://www.sqlshack.com/an-overview-of-the-sp_whoisactive-stored-procedure/

3.https://blog.csdn.net/culuo4781/article/details/107627065

原文链接:http://www.cnblogs.com/xuliuzai/p/14632168.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号