|
|
@@ -1,60 +1,44 @@
|
|
|
-- 2012-04-07 Pedro Lopes (Microsoft) (http://aka.ms/tigertoolbox/)
|
|
|
---
|
|
|
--- Returns running sessions/requests; blocking information; sessions that have been granted locks or waiting for locks; SPs stats.
|
|
|
---
|
|
|
--- 2012-09-10 Added extra information
|
|
|
--- 2013-02-02 Added extra information
|
|
|
--- 2013-04-12 Added page type information (PFS; GAM or SGAM) when wait type is PAGELATCH_ or PAGEIOLATCH_ .
|
|
|
--- 2013-05-23 Fixed parse page issue
|
|
|
--- 2013-09-16 Added mem grants information
|
|
|
--- 2013-10-17 Added statements to blocking and blocked sections, fixed head blocker info
|
|
|
--- 2013-12-09 Fixed blocking section showing non-blocked sessions also
|
|
|
--- 2014-02-04 Fixed conversion issue with blocking section
|
|
|
--- 2014-04-09 Added information to blocking section, and fixed conversion issue
|
|
|
--- 2014-12-09 Handle illegal characters in XML conversion
|
|
|
--- 11/16/2016 Added support for SQL Server 2016 SP1 and live query plan snapshot.
|
|
|
--- 12/2/2016 Fixed transport-level error issue with SQL Server 2016 SP1.
|
|
|
--- 2/16/2016 Added NOLOCK hints.
|
|
|
--- 3/28/2017 Fixed missing characters in offset fetches.
|
|
|
--- 10/11/2017 Commented out stored procedure/query stats section to optimize for in-flight requests.
|
|
|
--- 10/20/2017 Added Query stats section and support for sys.dm_exec_query_statistics_xml.
|
|
|
--- 04/02/2019 Added support for sys.dm_exec_query_plan_stats and trigger/function stats section.
|
|
|
|
|
|
+CREATE PROCEDURE usp_whatsup @uptime bit = 1, @requests bit = 1, @blocking bit = 1, @spstats bit = 0, @qrystats bit = 0, @trstats bit = 0, @fnstats bit = 0
|
|
|
+AS
|
|
|
|
|
|
-/*
|
|
|
-NOTE: Some sections are commented out for a quick default insight to in-flight requests.
|
|
|
- Uncomment section you would like to execute as well for a more holistic approach on executions.
|
|
|
-*/
|
|
|
+-- Returns running sessions/requests; blocking information; sessions that have been granted locks or waiting for locks; and optionally SP/Query/Trigger/Function execution stats.
|
|
|
|
|
|
SET NOCOUNT ON;
|
|
|
-DECLARE @UpTime VARCHAR(12), @StartDate DATETIME, @sqlmajorver int, @sqlcmd NVARCHAR(500), @params NVARCHAR(500)
|
|
|
-SELECT @sqlmajorver = CONVERT(int, (@@microsoftversion / 0x1000000) & 0xff);
|
|
|
|
|
|
-IF @sqlmajorver = 9
|
|
|
-BEGIN
|
|
|
- SET @sqlcmd = N'SELECT @StartDateOUT = login_time, @UpTimeOUT = DATEDIFF(mi, login_time, GETDATE()) FROM master..sysprocesses WHERE spid = 1';
|
|
|
-END
|
|
|
-ELSE
|
|
|
+DECLARE @sqlmajorver int, @sqlbuild int, @sqlcmd NVARCHAR(500), @params NVARCHAR(500)
|
|
|
+SELECT @sqlmajorver = CONVERT(int, (@@microsoftversion / 0x1000000) & 0xff);
|
|
|
+SELECT @sqlbuild = CONVERT(int, @@microsoftversion & 0xffff);
|
|
|
+
|
|
|
+IF @uptime = 1
|
|
|
BEGIN
|
|
|
- SET @sqlcmd = N'SELECT @StartDateOUT = sqlserver_start_time, @UpTimeOUT = DATEDIFF(mi,sqlserver_start_time,GETDATE()) FROM sys.dm_os_sys_info';
|
|
|
-END
|
|
|
+ DECLARE @UpTime VARCHAR(12), @StartDate DATETIME,
|
|
|
+
|
|
|
+ IF @sqlmajorver = 9
|
|
|
+ BEGIN
|
|
|
+ SET @sqlcmd = N'SELECT @StartDateOUT = login_time, @UpTimeOUT = DATEDIFF(mi, login_time, GETDATE()) FROM master..sysprocesses WHERE spid = 1';
|
|
|
+ END
|
|
|
+ ELSE
|
|
|
+ BEGIN
|
|
|
+ SET @sqlcmd = N'SELECT @StartDateOUT = sqlserver_start_time, @UpTimeOUT = DATEDIFF(mi,sqlserver_start_time,GETDATE()) FROM sys.dm_os_sys_info';
|
|
|
+ END
|
|
|
|
|
|
-SET @params = N'@StartDateOUT DATETIME OUTPUT, @UpTimeOUT VARCHAR(12) OUTPUT';
|
|
|
+ SET @params = N'@StartDateOUT DATETIME OUTPUT, @UpTimeOUT VARCHAR(12) OUTPUT';
|
|
|
|
|
|
-EXECUTE sp_executesql @sqlcmd, @params, @StartDateOUT=@StartDate OUTPUT, @UpTimeOUT=@UpTime OUTPUT;
|
|
|
+ EXECUTE sp_executesql @sqlcmd, @params, @StartDateOUT=@StartDate OUTPUT, @UpTimeOUT=@UpTime OUTPUT;
|
|
|
|
|
|
-SELECT 'Uptime_Information' AS [Information], GETDATE() AS [Current_Time], @StartDate AS Last_Startup, CONVERT(VARCHAR(4),@UpTime/60/24) + 'd ' + CONVERT(VARCHAR(4),@UpTime/60%24) + 'h ' + CONVERT(VARCHAR(4),@UpTime%60) + 'm' AS Uptime
|
|
|
+ SELECT 'Uptime_Information' AS [Information], GETDATE() AS [Current_Time], @StartDate AS Last_Startup, CONVERT(VARCHAR(4),@UpTime/60/24) + 'd ' + CONVERT(VARCHAR(4),@UpTime/60%24) + 'h ' + CONVERT(VARCHAR(4),@UpTime%60) + 'm' AS Uptime
|
|
|
|
|
|
---SELECT DATEDIFF(hh,'2011-09-08 11:35:00',GETDATE()) AS since_lst_clear
|
|
|
-GO
|
|
|
+ --SELECT DATEDIFF(hh,'2011-09-08 11:35:00',GETDATE()) AS since_lst_clear
|
|
|
+END;
|
|
|
|
|
|
-- Running Sessions/Requests Report
|
|
|
-DECLARE @sqlmajorver int, @sqlbuild int, @sqlcmd VARCHAR(8000)
|
|
|
-SELECT @sqlmajorver = CONVERT(int, (@@microsoftversion / 0x1000000) & 0xff);
|
|
|
-SELECT @sqlbuild = CONVERT(int, @@microsoftversion & 0xffff);
|
|
|
-IF @sqlmajorver = 9
|
|
|
+IF @requests = 1
|
|
|
BEGIN
|
|
|
- SELECT @sqlcmd = N'SELECT ''Requests'' AS [Information], es.session_id, DB_NAME(er.database_id) AS [database_name], OBJECT_NAME(qp.objectid, qp.dbid) AS [object_name], -- NULL if Ad-Hoc or Prepared statements
|
|
|
+ IF @sqlmajorver = 9
|
|
|
+ BEGIN
|
|
|
+ SELECT @sqlcmd = N'SELECT ''Requests'' AS [Information], es.session_id, DB_NAME(er.database_id) AS [database_name], OBJECT_NAME(qp.objectid, qp.dbid) AS [object_name], -- NULL if Ad-Hoc or Prepared statements
|
|
|
(SELECT REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
|
|
|
qt.text,
|
|
|
NCHAR(1),N''?''),NCHAR(2),N''?''),NCHAR(3),N''?''),NCHAR(4),N''?''),NCHAR(5),N''?''),NCHAR(6),N''?''),NCHAR(7),N''?''),NCHAR(8),N''?''),NCHAR(11),N''?''),NCHAR(12),N''?''),NCHAR(14),N''?''),NCHAR(15),N''?''),NCHAR(16),N''?''),NCHAR(17),N''?''),NCHAR(18),N''?''),NCHAR(19),N''?''),NCHAR(20),N''?''),NCHAR(21),N''?''),NCHAR(22),N''?''),NCHAR(23),N''?''),NCHAR(24),N''?''),NCHAR(25),N''?''),NCHAR(26),N''?''),NCHAR(27),N''?''),NCHAR(28),N''?''),NCHAR(29),N''?''),NCHAR(30),N''?''),NCHAR(31),N''?'')
|
|
|
@@ -123,10 +107,10 @@ FROM sys.dm_exec_requests (NOLOCK) er
|
|
|
OUTER APPLY sys.dm_exec_query_plan(er.plan_handle) qp
|
|
|
WHERE er.session_id <> @@SPID AND es.is_user_process = 1
|
|
|
ORDER BY er.total_elapsed_time DESC, er.logical_reads DESC, [database_name], session_id'
|
|
|
-END
|
|
|
-ELSE IF @sqlmajorver IN (10,11,12) OR (@sqlmajorver = 13 AND @sqlbuild < 4000)
|
|
|
-BEGIN
|
|
|
- SET @sqlcmd = N';WITH tsu AS (SELECT session_id, SUM(user_objects_alloc_page_count) AS user_objects_alloc_page_count,
|
|
|
+ END
|
|
|
+ ELSE IF @sqlmajorver IN (10,11,12) OR (@sqlmajorver = 13 AND @sqlbuild < 4000)
|
|
|
+ BEGIN
|
|
|
+ SET @sqlcmd = N';WITH tsu AS (SELECT session_id, SUM(user_objects_alloc_page_count) AS user_objects_alloc_page_count,
|
|
|
SUM(user_objects_dealloc_page_count) AS user_objects_dealloc_page_count,
|
|
|
SUM(internal_objects_alloc_page_count) AS internal_objects_alloc_page_count,
|
|
|
SUM(internal_objects_dealloc_page_count) AS internal_objects_dealloc_page_count FROM sys.dm_db_task_space_usage (NOLOCK) GROUP BY session_id)
|
|
|
@@ -207,10 +191,10 @@ FROM sys.dm_exec_requests (NOLOCK) er
|
|
|
OUTER APPLY sys.dm_exec_query_plan(er.plan_handle) qp
|
|
|
WHERE er.session_id <> @@SPID AND es.is_user_process = 1
|
|
|
ORDER BY er.total_elapsed_time DESC, er.logical_reads DESC, [database_name], session_id'
|
|
|
-END
|
|
|
-ELSE IF (@sqlmajorver = 13 AND @sqlbuild > 4000) OR @sqlmajorver = 14 OR (@sqlmajorver = 15 AND @sqlbuild < 1400)
|
|
|
-BEGIN
|
|
|
- SELECT @sqlcmd = N'WITH tsu AS (SELECT session_id, SUM(user_objects_alloc_page_count) AS user_objects_alloc_page_count,
|
|
|
+ END
|
|
|
+ ELSE IF (@sqlmajorver = 13 AND @sqlbuild > 4000) OR @sqlmajorver = 14 OR (@sqlmajorver = 15 AND @sqlbuild < 1400)
|
|
|
+ BEGIN
|
|
|
+ SELECT @sqlcmd = N'WITH tsu AS (SELECT session_id, SUM(user_objects_alloc_page_count) AS user_objects_alloc_page_count,
|
|
|
SUM(user_objects_dealloc_page_count) AS user_objects_dealloc_page_count,
|
|
|
SUM(internal_objects_alloc_page_count) AS internal_objects_alloc_page_count,
|
|
|
SUM(internal_objects_dealloc_page_count) AS internal_objects_dealloc_page_count FROM sys.dm_db_task_space_usage (NOLOCK) GROUP BY session_id)
|
|
|
@@ -293,10 +277,10 @@ FROM sys.dm_exec_requests (NOLOCK) er
|
|
|
OUTER APPLY sys.dm_exec_query_statistics_xml(er.session_id) qes
|
|
|
WHERE er.session_id <> @@SPID AND es.is_user_process = 1
|
|
|
ORDER BY er.total_elapsed_time DESC, er.logical_reads DESC, [database_name], session_id'
|
|
|
-END
|
|
|
-ELSE IF (@sqlmajorver = 15 AND @sqlbuild >= 1400) OR @sqlmajorver > 15
|
|
|
-BEGIN
|
|
|
- SELECT @sqlcmd = N'WITH tsu AS (SELECT session_id, SUM(user_objects_alloc_page_count) AS user_objects_alloc_page_count,
|
|
|
+ END
|
|
|
+ ELSE IF (@sqlmajorver = 15 AND @sqlbuild >= 1400) OR @sqlmajorver > 15
|
|
|
+ BEGIN
|
|
|
+ SELECT @sqlcmd = N'WITH tsu AS (SELECT session_id, SUM(user_objects_alloc_page_count) AS user_objects_alloc_page_count,
|
|
|
SUM(user_objects_dealloc_page_count) AS user_objects_dealloc_page_count,
|
|
|
SUM(internal_objects_alloc_page_count) AS internal_objects_alloc_page_count,
|
|
|
SUM(internal_objects_dealloc_page_count) AS internal_objects_dealloc_page_count FROM sys.dm_db_task_space_usage (NOLOCK) GROUP BY session_id)
|
|
|
@@ -374,142 +358,141 @@ FROM sys.dm_exec_requests (NOLOCK) er
|
|
|
OUTER APPLY sys.dm_db_page_info(pc.db_id, pc.file_id, pc.page_id, ''LIMITED'') pi
|
|
|
WHERE er.session_id <> @@SPID AND es.is_user_process = 1
|
|
|
ORDER BY er.total_elapsed_time DESC, er.logical_reads DESC, [database_name], session_id'
|
|
|
-END
|
|
|
---PRINT @sqlcmd
|
|
|
-EXECUTE (@sqlcmd)
|
|
|
-GO
|
|
|
+ END
|
|
|
+
|
|
|
+ EXECUTE (@sqlcmd)
|
|
|
+END;
|
|
|
|
|
|
-- Waiter and Blocking Report
|
|
|
-SELECT 'Waiter_Blocking_Report' AS [Information],
|
|
|
- -- blocked
|
|
|
- es.session_id AS blocked_spid,
|
|
|
- es.[status] AS [blocked_spid_status],
|
|
|
- ot.task_state AS [blocked_task_status],
|
|
|
- owt.wait_type AS blocked_spid_wait_type,
|
|
|
- COALESCE(owt.wait_duration_ms, DATEDIFF(ms, es.last_request_start_time, GETDATE())) AS blocked_spid_wait_time_ms,
|
|
|
- --er.total_elapsed_time AS blocked_elapsed_time_ms,
|
|
|
- /*
|
|
|
- Check sys.dm_os_waiting_tasks for Exchange wait types in http://technet.microsoft.com/en-us/library/ms188743.aspx.
|
|
|
- - Wait Resource e_waitPipeNewRow in CXPACKET waits – Producer waiting on consumer for a packet to fill.
|
|
|
- - Wait Resource e_waitPipeGetRow in CXPACKET waits – Consumer waiting on producer to fill a packet.
|
|
|
- */
|
|
|
- owt.resource_description AS blocked_spid_res_desc,
|
|
|
- owt.[objid] AS blocked_objectid,
|
|
|
- owt.pageid AS blocked_pageid,
|
|
|
- CASE WHEN owt.pageid = 1 OR owt.pageid % 8088 = 0 THEN 'Is_PFS_Page'
|
|
|
- WHEN owt.pageid = 2 OR owt.pageid % 511232 = 0 THEN 'Is_GAM_Page'
|
|
|
- WHEN owt.pageid = 3 OR (owt.pageid - 1) % 511232 = 0 THEN 'Is_SGAM_Page'
|
|
|
- WHEN owt.pageid IS NULL THEN NULL
|
|
|
- ELSE 'Is_not_PFS_GAM_SGAM_page' END AS blocked_spid_res_type,
|
|
|
- (SELECT qt.text AS [text()]
|
|
|
- FROM sys.dm_exec_sql_text(COALESCE(er.sql_handle, ec.most_recent_sql_handle)) AS qt
|
|
|
- FOR XML PATH(''), TYPE) AS [blocked_batch],
|
|
|
- (SELECT SUBSTRING(qt2.text,
|
|
|
- 1+(CASE WHEN er.statement_start_offset = 0 THEN 0 ELSE er.statement_start_offset/2 END),
|
|
|
- 1+(CASE WHEN er.statement_end_offset = -1 THEN DATALENGTH(qt2.text) ELSE er.statement_end_offset/2 END - (CASE WHEN er.statement_start_offset = 0 THEN 0 ELSE er.statement_start_offset/2 END))) AS [text()]
|
|
|
- FROM sys.dm_exec_sql_text(COALESCE(er.sql_handle, ec.most_recent_sql_handle)) AS qt2
|
|
|
- FOR XML PATH(''), TYPE) AS [blocked_statement],
|
|
|
- es.last_request_start_time AS blocked_last_start,
|
|
|
- LEFT (CASE COALESCE(es.transaction_isolation_level, er.transaction_isolation_level)
|
|
|
- WHEN 0 THEN '0-Unspecified'
|
|
|
- WHEN 1 THEN '1-ReadUncommitted(NOLOCK)'
|
|
|
- WHEN 2 THEN '2-ReadCommitted'
|
|
|
- WHEN 3 THEN '3-RepeatableRead'
|
|
|
- WHEN 4 THEN '4-Serializable'
|
|
|
- WHEN 5 THEN '5-Snapshot'
|
|
|
- ELSE CONVERT (VARCHAR(30), COALESCE(es.transaction_isolation_level, er.transaction_isolation_level)) + '-UNKNOWN'
|
|
|
- END, 30) AS blocked_tran_isolation_level,
|
|
|
+IF @blocking = 1
|
|
|
+BEGIN
|
|
|
+ SELECT 'Waiter_Blocking_Report' AS [Information],
|
|
|
+ -- blocked
|
|
|
+ es.session_id AS blocked_spid,
|
|
|
+ es.[status] AS [blocked_spid_status],
|
|
|
+ ot.task_state AS [blocked_task_status],
|
|
|
+ owt.wait_type AS blocked_spid_wait_type,
|
|
|
+ COALESCE(owt.wait_duration_ms, DATEDIFF(ms, es.last_request_start_time, GETDATE())) AS blocked_spid_wait_time_ms,
|
|
|
+ --er.total_elapsed_time AS blocked_elapsed_time_ms,
|
|
|
+ /*
|
|
|
+ Check sys.dm_os_waiting_tasks for Exchange wait types in http://technet.microsoft.com/en-us/library/ms188743.aspx.
|
|
|
+ - Wait Resource e_waitPipeNewRow in CXPACKET waits – Producer waiting on consumer for a packet to fill.
|
|
|
+ - Wait Resource e_waitPipeGetRow in CXPACKET waits – Consumer waiting on producer to fill a packet.
|
|
|
+ */
|
|
|
+ owt.resource_description AS blocked_spid_res_desc,
|
|
|
+ owt.[objid] AS blocked_objectid,
|
|
|
+ owt.pageid AS blocked_pageid,
|
|
|
+ CASE WHEN owt.pageid = 1 OR owt.pageid % 8088 = 0 THEN 'Is_PFS_Page'
|
|
|
+ WHEN owt.pageid = 2 OR owt.pageid % 511232 = 0 THEN 'Is_GAM_Page'
|
|
|
+ WHEN owt.pageid = 3 OR (owt.pageid - 1) % 511232 = 0 THEN 'Is_SGAM_Page'
|
|
|
+ WHEN owt.pageid IS NULL THEN NULL
|
|
|
+ ELSE 'Is_not_PFS_GAM_SGAM_page' END AS blocked_spid_res_type,
|
|
|
+ (SELECT qt.text AS [text()]
|
|
|
+ FROM sys.dm_exec_sql_text(COALESCE(er.sql_handle, ec.most_recent_sql_handle)) AS qt
|
|
|
+ FOR XML PATH(''), TYPE) AS [blocked_batch],
|
|
|
+ (SELECT SUBSTRING(qt2.text,
|
|
|
+ 1+(CASE WHEN er.statement_start_offset = 0 THEN 0 ELSE er.statement_start_offset/2 END),
|
|
|
+ 1+(CASE WHEN er.statement_end_offset = -1 THEN DATALENGTH(qt2.text) ELSE er.statement_end_offset/2 END - (CASE WHEN er.statement_start_offset = 0 THEN 0 ELSE er.statement_start_offset/2 END))) AS [text()]
|
|
|
+ FROM sys.dm_exec_sql_text(COALESCE(er.sql_handle, ec.most_recent_sql_handle)) AS qt2
|
|
|
+ FOR XML PATH(''), TYPE) AS [blocked_statement],
|
|
|
+ es.last_request_start_time AS blocked_last_start,
|
|
|
+ LEFT (CASE COALESCE(es.transaction_isolation_level, er.transaction_isolation_level)
|
|
|
+ WHEN 0 THEN '0-Unspecified'
|
|
|
+ WHEN 1 THEN '1-ReadUncommitted(NOLOCK)'
|
|
|
+ WHEN 2 THEN '2-ReadCommitted'
|
|
|
+ WHEN 3 THEN '3-RepeatableRead'
|
|
|
+ WHEN 4 THEN '4-Serializable'
|
|
|
+ WHEN 5 THEN '5-Snapshot'
|
|
|
+ ELSE CONVERT (VARCHAR(30), COALESCE(es.transaction_isolation_level, er.transaction_isolation_level)) + '-UNKNOWN'
|
|
|
+ END, 30) AS blocked_tran_isolation_level,
|
|
|
|
|
|
- -- blocker
|
|
|
- er.blocking_session_id As blocker_spid,
|
|
|
- CASE
|
|
|
- -- session has an active request, is blocked, but is blocking others or session is idle but has an open tran and is blocking others
|
|
|
- WHEN (er2.session_id IS NULL OR owt.blocking_session_id IS NULL) AND (er.blocking_session_id = 0 OR er.session_id IS NULL) THEN 1
|
|
|
- -- session is either not blocking someone, or is blocking someone but is blocked by another party
|
|
|
- ELSE 0
|
|
|
- END AS is_head_blocker,
|
|
|
- (SELECT REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
|
|
|
- qt2.text,
|
|
|
- NCHAR(1),N'?'),NCHAR(2),N'?'),NCHAR(3),N'?'),NCHAR(4),N'?'),NCHAR(5),N'?'),NCHAR(6),N'?'),NCHAR(7),N'?'),NCHAR(8),N'?'),NCHAR(11),N'?'),NCHAR(12),N'?'),NCHAR(14),N'?'),NCHAR(15),N'?'),NCHAR(16),N'?'),NCHAR(17),N'?'),NCHAR(18),N'?'),NCHAR(19),N'?'),NCHAR(20),N'?'),NCHAR(21),N'?'),NCHAR(22),N'?'),NCHAR(23),N'?'),NCHAR(24),N'?'),NCHAR(25),N'?'),NCHAR(26),N'?'),NCHAR(27),N'?'),NCHAR(28),N'?'),NCHAR(29),N'?'),NCHAR(30),N'?'),NCHAR(31),N'?')
|
|
|
- AS [text()]
|
|
|
- FROM sys.dm_exec_sql_text(COALESCE(er2.sql_handle, ec2.most_recent_sql_handle)) AS qt2
|
|
|
- FOR XML PATH(''), TYPE) AS [blocker_batch],
|
|
|
- (SELECT REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
|
|
|
- SUBSTRING(qt2.text,
|
|
|
- 1+(CASE WHEN er2.statement_start_offset = 0 THEN 0 ELSE er2.statement_start_offset/2 END),
|
|
|
- 1+(CASE WHEN er2.statement_end_offset = -1 THEN DATALENGTH(qt2.text) ELSE er2.statement_end_offset/2 END - (CASE WHEN er2.statement_start_offset = 0 THEN 0 ELSE er2.statement_start_offset/2 END))),
|
|
|
- NCHAR(1),N'?'),NCHAR(2),N'?'),NCHAR(3),N'?'),NCHAR(4),N'?'),NCHAR(5),N'?'),NCHAR(6),N'?'),NCHAR(7),N'?'),NCHAR(8),N'?'),NCHAR(11),N'?'),NCHAR(12),N'?'),NCHAR(14),N'?'),NCHAR(15),N'?'),NCHAR(16),N'?'),NCHAR(17),N'?'),NCHAR(18),N'?'),NCHAR(19),N'?'),NCHAR(20),N'?'),NCHAR(21),N'?'),NCHAR(22),N'?'),NCHAR(23),N'?'),NCHAR(24),N'?'),NCHAR(25),N'?'),NCHAR(26),N'?'),NCHAR(27),N'?'),NCHAR(28),N'?'),NCHAR(29),N'?'),NCHAR(30),N'?'),NCHAR(31),N'?')
|
|
|
- AS [text()]
|
|
|
- FROM sys.dm_exec_sql_text(COALESCE(er2.sql_handle, ec2.most_recent_sql_handle)) AS qt2
|
|
|
- FOR XML PATH(''), TYPE) AS [blocker_statement],
|
|
|
- es2.last_request_start_time AS blocker_last_start,
|
|
|
- LEFT (CASE COALESCE(er2.transaction_isolation_level, es.transaction_isolation_level)
|
|
|
- WHEN 0 THEN '0-Unspecified'
|
|
|
- WHEN 1 THEN '1-ReadUncommitted(NOLOCK)'
|
|
|
- WHEN 2 THEN '2-ReadCommitted'
|
|
|
- WHEN 3 THEN '3-RepeatableRead'
|
|
|
- WHEN 4 THEN '4-Serializable'
|
|
|
- WHEN 5 THEN '5-Snapshot'
|
|
|
- ELSE CONVERT (VARCHAR(30), COALESCE(er2.transaction_isolation_level, es.transaction_isolation_level)) + '-UNKNOWN'
|
|
|
- END, 30) AS blocker_tran_isolation_level,
|
|
|
+ -- blocker
|
|
|
+ er.blocking_session_id As blocker_spid,
|
|
|
+ CASE
|
|
|
+ -- session has an active request, is blocked, but is blocking others or session is idle but has an open tran and is blocking others
|
|
|
+ WHEN (er2.session_id IS NULL OR owt.blocking_session_id IS NULL) AND (er.blocking_session_id = 0 OR er.session_id IS NULL) THEN 1
|
|
|
+ -- session is either not blocking someone, or is blocking someone but is blocked by another party
|
|
|
+ ELSE 0
|
|
|
+ END AS is_head_blocker,
|
|
|
+ (SELECT REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
|
|
|
+ qt2.text,
|
|
|
+ NCHAR(1),N'?'),NCHAR(2),N'?'),NCHAR(3),N'?'),NCHAR(4),N'?'),NCHAR(5),N'?'),NCHAR(6),N'?'),NCHAR(7),N'?'),NCHAR(8),N'?'),NCHAR(11),N'?'),NCHAR(12),N'?'),NCHAR(14),N'?'),NCHAR(15),N'?'),NCHAR(16),N'?'),NCHAR(17),N'?'),NCHAR(18),N'?'),NCHAR(19),N'?'),NCHAR(20),N'?'),NCHAR(21),N'?'),NCHAR(22),N'?'),NCHAR(23),N'?'),NCHAR(24),N'?'),NCHAR(25),N'?'),NCHAR(26),N'?'),NCHAR(27),N'?'),NCHAR(28),N'?'),NCHAR(29),N'?'),NCHAR(30),N'?'),NCHAR(31),N'?')
|
|
|
+ AS [text()]
|
|
|
+ FROM sys.dm_exec_sql_text(COALESCE(er2.sql_handle, ec2.most_recent_sql_handle)) AS qt2
|
|
|
+ FOR XML PATH(''), TYPE) AS [blocker_batch],
|
|
|
+ (SELECT REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
|
|
|
+ SUBSTRING(qt2.text,
|
|
|
+ 1+(CASE WHEN er2.statement_start_offset = 0 THEN 0 ELSE er2.statement_start_offset/2 END),
|
|
|
+ 1+(CASE WHEN er2.statement_end_offset = -1 THEN DATALENGTH(qt2.text) ELSE er2.statement_end_offset/2 END - (CASE WHEN er2.statement_start_offset = 0 THEN 0 ELSE er2.statement_start_offset/2 END))),
|
|
|
+ NCHAR(1),N'?'),NCHAR(2),N'?'),NCHAR(3),N'?'),NCHAR(4),N'?'),NCHAR(5),N'?'),NCHAR(6),N'?'),NCHAR(7),N'?'),NCHAR(8),N'?'),NCHAR(11),N'?'),NCHAR(12),N'?'),NCHAR(14),N'?'),NCHAR(15),N'?'),NCHAR(16),N'?'),NCHAR(17),N'?'),NCHAR(18),N'?'),NCHAR(19),N'?'),NCHAR(20),N'?'),NCHAR(21),N'?'),NCHAR(22),N'?'),NCHAR(23),N'?'),NCHAR(24),N'?'),NCHAR(25),N'?'),NCHAR(26),N'?'),NCHAR(27),N'?'),NCHAR(28),N'?'),NCHAR(29),N'?'),NCHAR(30),N'?'),NCHAR(31),N'?')
|
|
|
+ AS [text()]
|
|
|
+ FROM sys.dm_exec_sql_text(COALESCE(er2.sql_handle, ec2.most_recent_sql_handle)) AS qt2
|
|
|
+ FOR XML PATH(''), TYPE) AS [blocker_statement],
|
|
|
+ es2.last_request_start_time AS blocker_last_start,
|
|
|
+ LEFT (CASE COALESCE(er2.transaction_isolation_level, es.transaction_isolation_level)
|
|
|
+ WHEN 0 THEN '0-Unspecified'
|
|
|
+ WHEN 1 THEN '1-ReadUncommitted(NOLOCK)'
|
|
|
+ WHEN 2 THEN '2-ReadCommitted'
|
|
|
+ WHEN 3 THEN '3-RepeatableRead'
|
|
|
+ WHEN 4 THEN '4-Serializable'
|
|
|
+ WHEN 5 THEN '5-Snapshot'
|
|
|
+ ELSE CONVERT (VARCHAR(30), COALESCE(er2.transaction_isolation_level, es.transaction_isolation_level)) + '-UNKNOWN'
|
|
|
+ END, 30) AS blocker_tran_isolation_level,
|
|
|
|
|
|
- -- blocked - other data
|
|
|
- DB_NAME(er.database_id) AS blocked_database,
|
|
|
- es.[host_name] AS blocked_host,
|
|
|
- es.[program_name] AS blocked_program,
|
|
|
- es.login_name AS blocked_login,
|
|
|
- CASE WHEN es.session_id = -2 THEN 'Orphaned_distributed_tran'
|
|
|
- WHEN es.session_id = -3 THEN 'Defered_recovery_tran'
|
|
|
- WHEN es.session_id = -4 THEN 'Unknown_tran' ELSE NULL END AS blocked_session_comment,
|
|
|
- es.is_user_process AS [blocked_is_user_process],
|
|
|
+ -- blocked - other data
|
|
|
+ DB_NAME(er.database_id) AS blocked_database,
|
|
|
+ es.[host_name] AS blocked_host,
|
|
|
+ es.[program_name] AS blocked_program,
|
|
|
+ es.login_name AS blocked_login,
|
|
|
+ CASE WHEN es.session_id = -2 THEN 'Orphaned_distributed_tran'
|
|
|
+ WHEN es.session_id = -3 THEN 'Defered_recovery_tran'
|
|
|
+ WHEN es.session_id = -4 THEN 'Unknown_tran' ELSE NULL END AS blocked_session_comment,
|
|
|
+ es.is_user_process AS [blocked_is_user_process],
|
|
|
|
|
|
- -- blocker - other data
|
|
|
- DB_NAME(er2.database_id) AS blocker_database,
|
|
|
- es2.[host_name] AS blocker_host,
|
|
|
- es2.[program_name] AS blocker_program,
|
|
|
- es2.login_name AS blocker_login,
|
|
|
- CASE WHEN es2.session_id = -2 THEN 'Orphaned_distributed_tran'
|
|
|
- WHEN es2.session_id = -3 THEN 'Defered_recovery_tran'
|
|
|
- WHEN es2.session_id = -4 THEN 'Unknown_tran' ELSE NULL END AS blocker_session_comment,
|
|
|
- es2.is_user_process AS [blocker_is_user_process]
|
|
|
-FROM sys.dm_exec_sessions (NOLOCK) es
|
|
|
-LEFT OUTER JOIN sys.dm_exec_requests (NOLOCK) er ON es.session_id = er.session_id
|
|
|
-LEFT OUTER JOIN sys.dm_exec_connections (NOLOCK) ec ON es.session_id = ec.session_id
|
|
|
-LEFT OUTER JOIN sys.dm_os_tasks (NOLOCK) ot ON er.session_id = ot.session_id AND er.request_id = ot.request_id
|
|
|
-LEFT OUTER JOIN sys.dm_exec_sessions (NOLOCK) es2 ON er.blocking_session_id = es2.session_id
|
|
|
-LEFT OUTER JOIN sys.dm_exec_requests (NOLOCK) er2 ON es2.session_id = er2.session_id
|
|
|
-LEFT OUTER JOIN sys.dm_exec_connections (NOLOCK) ec2 ON es2.session_id = ec2.session_id
|
|
|
-LEFT OUTER JOIN
|
|
|
-(
|
|
|
- -- In some cases (e.g. parallel queries, also waiting for a worker), one thread can be flagged as
|
|
|
- -- waiting for several different threads. This will cause that thread to show up in multiple rows
|
|
|
- -- in our grid, which we don't want. Use ROW_NUMBER to select the longest wait for each thread,
|
|
|
- -- and use it as representative of the other wait relationships this thread is involved in.
|
|
|
- SELECT waiting_task_address, session_id, exec_context_id, wait_duration_ms,
|
|
|
- wait_type, resource_address, blocking_task_address, blocking_session_id,
|
|
|
- blocking_exec_context_id, resource_description,
|
|
|
- CASE WHEN [wait_type] LIKE 'PAGE%' AND [resource_description] LIKE '%:%' THEN CAST(RIGHT([resource_description], LEN([resource_description]) - CHARINDEX(':', [resource_description], LEN([resource_description])-CHARINDEX(':', REVERSE([resource_description])))) AS int)
|
|
|
- WHEN [wait_type] LIKE 'LCK%' AND [resource_description] LIKE '%pageid%' AND ISNUMERIC(RIGHT(LEFT([resource_description],CHARINDEX('dbid=', [resource_description], CHARINDEX('pageid=', [resource_description])+6)-1),CHARINDEX('=',REVERSE(RTRIM(LEFT([resource_description],CHARINDEX('dbid=', [resource_description], CHARINDEX('pageid=', [resource_description])+6)-1)))))) = 1 THEN CAST(RIGHT(LEFT([resource_description],CHARINDEX('dbid=', [resource_description], CHARINDEX('pageid=', [resource_description])+6)-1),CHARINDEX('=',REVERSE(RTRIM(LEFT([resource_description],CHARINDEX('dbid=', [resource_description], CHARINDEX('pageid=', [resource_description])+6)-1))))) AS bigint)
|
|
|
- ELSE NULL END AS pageid,
|
|
|
- CASE WHEN [wait_type] LIKE 'LCK%' AND [resource_description] LIKE '%associatedObjectId%' AND ISNUMERIC(RIGHT([resource_description],CHARINDEX('=', REVERSE([resource_description]))-1)) = 1 THEN CAST(RIGHT([resource_description],CHARINDEX('=', REVERSE([resource_description]))-1) AS bigint)
|
|
|
- ELSE NULL END AS [objid],
|
|
|
- ROW_NUMBER() OVER (PARTITION BY waiting_task_address ORDER BY wait_duration_ms DESC) AS row_num
|
|
|
- FROM sys.dm_os_waiting_tasks (NOLOCK)
|
|
|
-) owt ON ot.task_address = owt.waiting_task_address AND owt.row_num = 1
|
|
|
---OUTER APPLY sys.dm_exec_sql_text(er.sql_handle) est
|
|
|
---OUTER APPLY sys.dm_exec_query_plan(er.plan_handle) eqp
|
|
|
-WHERE es.session_id <> @@SPID AND es.is_user_process = 1
|
|
|
- --AND ((owt.wait_duration_ms/1000 > 5) OR (er.total_elapsed_time/1000) > 5 OR er.total_elapsed_time IS NULL) --Only report blocks > 5 Seconds plus head blocker
|
|
|
- AND (es.session_id IN (SELECT er3.blocking_session_id FROM sys.dm_exec_requests (NOLOCK) er3) OR er.blocking_session_id IS NOT NULL OR er.blocking_session_id > 0)
|
|
|
-ORDER BY blocked_spid, is_head_blocker DESC, blocked_spid_wait_time_ms DESC, blocker_spid
|
|
|
+ -- blocker - other data
|
|
|
+ DB_NAME(er2.database_id) AS blocker_database,
|
|
|
+ es2.[host_name] AS blocker_host,
|
|
|
+ es2.[program_name] AS blocker_program,
|
|
|
+ es2.login_name AS blocker_login,
|
|
|
+ CASE WHEN es2.session_id = -2 THEN 'Orphaned_distributed_tran'
|
|
|
+ WHEN es2.session_id = -3 THEN 'Defered_recovery_tran'
|
|
|
+ WHEN es2.session_id = -4 THEN 'Unknown_tran' ELSE NULL END AS blocker_session_comment,
|
|
|
+ es2.is_user_process AS [blocker_is_user_process]
|
|
|
+ FROM sys.dm_exec_sessions (NOLOCK) es
|
|
|
+ LEFT OUTER JOIN sys.dm_exec_requests (NOLOCK) er ON es.session_id = er.session_id
|
|
|
+ LEFT OUTER JOIN sys.dm_exec_connections (NOLOCK) ec ON es.session_id = ec.session_id
|
|
|
+ LEFT OUTER JOIN sys.dm_os_tasks (NOLOCK) ot ON er.session_id = ot.session_id AND er.request_id = ot.request_id
|
|
|
+ LEFT OUTER JOIN sys.dm_exec_sessions (NOLOCK) es2 ON er.blocking_session_id = es2.session_id
|
|
|
+ LEFT OUTER JOIN sys.dm_exec_requests (NOLOCK) er2 ON es2.session_id = er2.session_id
|
|
|
+ LEFT OUTER JOIN sys.dm_exec_connections (NOLOCK) ec2 ON es2.session_id = ec2.session_id
|
|
|
+ LEFT OUTER JOIN
|
|
|
+ (
|
|
|
+ -- In some cases (e.g. parallel queries, also waiting for a worker), one thread can be flagged as
|
|
|
+ -- waiting for several different threads. This will cause that thread to show up in multiple rows
|
|
|
+ -- in our grid, which we don't want. Use ROW_NUMBER to select the longest wait for each thread,
|
|
|
+ -- and use it as representative of the other wait relationships this thread is involved in.
|
|
|
+ SELECT waiting_task_address, session_id, exec_context_id, wait_duration_ms,
|
|
|
+ wait_type, resource_address, blocking_task_address, blocking_session_id,
|
|
|
+ blocking_exec_context_id, resource_description,
|
|
|
+ CASE WHEN [wait_type] LIKE 'PAGE%' AND [resource_description] LIKE '%:%' THEN CAST(RIGHT([resource_description], LEN([resource_description]) - CHARINDEX(':', [resource_description], LEN([resource_description])-CHARINDEX(':', REVERSE([resource_description])))) AS int)
|
|
|
+ WHEN [wait_type] LIKE 'LCK%' AND [resource_description] LIKE '%pageid%' AND ISNUMERIC(RIGHT(LEFT([resource_description],CHARINDEX('dbid=', [resource_description], CHARINDEX('pageid=', [resource_description])+6)-1),CHARINDEX('=',REVERSE(RTRIM(LEFT([resource_description],CHARINDEX('dbid=', [resource_description], CHARINDEX('pageid=', [resource_description])+6)-1)))))) = 1 THEN CAST(RIGHT(LEFT([resource_description],CHARINDEX('dbid=', [resource_description], CHARINDEX('pageid=', [resource_description])+6)-1),CHARINDEX('=',REVERSE(RTRIM(LEFT([resource_description],CHARINDEX('dbid=', [resource_description], CHARINDEX('pageid=', [resource_description])+6)-1))))) AS bigint)
|
|
|
+ ELSE NULL END AS pageid,
|
|
|
+ CASE WHEN [wait_type] LIKE 'LCK%' AND [resource_description] LIKE '%associatedObjectId%' AND ISNUMERIC(RIGHT([resource_description],CHARINDEX('=', REVERSE([resource_description]))-1)) = 1 THEN CAST(RIGHT([resource_description],CHARINDEX('=', REVERSE([resource_description]))-1) AS bigint)
|
|
|
+ ELSE NULL END AS [objid],
|
|
|
+ ROW_NUMBER() OVER (PARTITION BY waiting_task_address ORDER BY wait_duration_ms DESC) AS row_num
|
|
|
+ FROM sys.dm_os_waiting_tasks (NOLOCK)
|
|
|
+ ) owt ON ot.task_address = owt.waiting_task_address AND owt.row_num = 1
|
|
|
+ --OUTER APPLY sys.dm_exec_sql_text(er.sql_handle) est
|
|
|
+ --OUTER APPLY sys.dm_exec_query_plan(er.plan_handle) eqp
|
|
|
+ WHERE es.session_id <> @@SPID AND es.is_user_process = 1
|
|
|
+ --AND ((owt.wait_duration_ms/1000 > 5) OR (er.total_elapsed_time/1000) > 5 OR er.total_elapsed_time IS NULL) --Only report blocks > 5 Seconds plus head blocker
|
|
|
+ AND (es.session_id IN (SELECT er3.blocking_session_id FROM sys.dm_exec_requests (NOLOCK) er3) OR er.blocking_session_id IS NOT NULL OR er.blocking_session_id > 0)
|
|
|
+ ORDER BY blocked_spid, is_head_blocker DESC, blocked_spid_wait_time_ms DESC, blocker_spid
|
|
|
+END;
|
|
|
|
|
|
-/*
|
|
|
-- Stored procedure stats
|
|
|
-DECLARE @sqlmajorver int, @sqlcmd VARCHAR(4000)
|
|
|
-SELECT @sqlmajorver = CONVERT(int, (@@microsoftversion / 0x1000000) & 0xff);
|
|
|
-
|
|
|
-IF @sqlmajorver >= 11
|
|
|
-BEGIN
|
|
|
+IF @spstats = 1 AND @sqlmajorver >= 11
|
|
|
+BEGIN
|
|
|
SET @sqlcmd = N'SELECT CASE WHEN ps.database_id = 32767 THEN ''ResourceDB'' ELSE DB_NAME(ps.database_id) END AS DatabaseName,
|
|
|
CASE WHEN ps.database_id = 32767 THEN NULL ELSE OBJECT_NAME(ps.[object_id], ps.database_id) END AS ObjectName,
|
|
|
type_desc,
|
|
|
@@ -535,11 +518,11 @@ BEGIN
|
|
|
FROM sys.dm_exec_procedure_stats (NOLOCK) ps
|
|
|
CROSS APPLY sys.dm_exec_query_plan(ps.plan_handle) qp'
|
|
|
EXEC (@sqlcmd);
|
|
|
- END
|
|
|
+END;
|
|
|
|
|
|
-- Query stats
|
|
|
-IF @sqlmajorver >= 11
|
|
|
-BEGIN
|
|
|
+IF @qrystats = 1 AND @sqlmajorver >= 11
|
|
|
+BEGIN
|
|
|
SET @sqlcmd = N'SELECT CASE WHEN CONVERT(int,pa.value) = 32767 THEN ''ResourceDB'' ELSE DB_NAME(CONVERT(int,pa.value)) END AS DatabaseName,
|
|
|
(SELECT st.text AS [text()] FROM sys.dm_exec_sql_text(qs.plan_handle) AS st FOR XML PATH(''''), TYPE) AS [sqltext],
|
|
|
qs.creation_time AS cached_time,
|
|
|
@@ -560,10 +543,10 @@ FROM sys.dm_exec_query_stats (NOLOCK) AS qs
|
|
|
CROSS APPLY sys.dm_exec_plan_attributes(qs.plan_handle) AS pa
|
|
|
WHERE pa.attribute = ''dbid'''
|
|
|
EXEC (@sqlcmd);
|
|
|
-END
|
|
|
+END;
|
|
|
|
|
|
-- Trigger stats
|
|
|
-IF @sqlmajorver >= 11
|
|
|
+IF @trstats = 1 AND @sqlmajorver >= 11
|
|
|
BEGIN
|
|
|
SET @sqlcmd = N'SELECT CASE WHEN ts.database_id = 32767 THEN ''ResourceDB'' ELSE DB_NAME(ts.database_id) END AS DatabaseName,
|
|
|
CASE WHEN ts.database_id = 32767 THEN NULL ELSE OBJECT_NAME(ts.[object_id], ts.database_id) END AS ObjectName,
|
|
|
@@ -587,13 +570,13 @@ BEGIN
|
|
|
ts.last_physical_reads, ts.min_physical_reads, ts.max_physical_reads,
|
|
|
ts.total_logical_writes/ts.execution_count AS avg_logical_writes,
|
|
|
ts.last_logical_writes, ts.min_logical_writes, ts.max_logical_writes
|
|
|
- FROM sys.dm_exec_trigger_stats (NOLOCK) ts
|
|
|
- CROSS APPLY sys.dm_exec_query_plan(ts.plan_handle) qp'
|
|
|
+FROM sys.dm_exec_trigger_stats (NOLOCK) ts
|
|
|
+CROSS APPLY sys.dm_exec_query_plan(ts.plan_handle) qp'
|
|
|
EXEC (@sqlcmd);
|
|
|
-END
|
|
|
+END;
|
|
|
|
|
|
-- Function stats
|
|
|
-IF @sqlmajorver >= 11
|
|
|
+IF @fnstats = 1 AND @sqlmajorver >= 11
|
|
|
BEGIN
|
|
|
SET @sqlcmd = N'SELECT CASE WHEN fs.database_id = 32767 THEN ''ResourceDB'' ELSE DB_NAME(fs.database_id) END AS DatabaseName,
|
|
|
CASE WHEN fs.database_id = 32767 THEN NULL ELSE OBJECT_NAME(fs.[object_id], fs.database_id) END AS ObjectName,
|
|
|
@@ -617,15 +600,7 @@ BEGIN
|
|
|
fs.last_physical_reads, fs.min_physical_reads, fs.max_physical_reads,
|
|
|
fs.total_logical_writes/fs.execution_count AS avg_logical_writes,
|
|
|
fs.last_logical_writes, fs.min_logical_writes, fs.max_logical_writes
|
|
|
- FROM sys.dm_exec_function_stats (NOLOCK) fs
|
|
|
- CROSS APPLY sys.dm_exec_query_plan(fs.plan_handle) qp'
|
|
|
+FROM sys.dm_exec_function_stats (NOLOCK) fs
|
|
|
+CROSS APPLY sys.dm_exec_query_plan(fs.plan_handle) qp'
|
|
|
EXEC (@sqlcmd);
|
|
|
-END
|
|
|
-*/
|
|
|
-
|
|
|
-/*
|
|
|
--- Acquired locks
|
|
|
-SELECT tl.*, sp.[object_id], sp.index_id
|
|
|
-FROM sys.dm_tran_locks (NOLOCK) tl
|
|
|
-LEFT JOIN sys.partitions (NOLOCK) sp ON tl.resource_associated_entity_id = sp.[hobt_id]
|
|
|
-*/
|
|
|
+END;
|