USE [DD_SYS] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO -- [PRDD_GET_DB_DEADLOCKS] -- ================================================================= -- Gets db deadlock victims -- Minimum requirement: MS SQL Server 2016 -- -- Returns: table -- ================================================================= -- Copyright (c) 2025 by Digital Data GmbH -- -- Digital Data GmbH • Ludwig-Rinn-Strasse 16 • D-35452 Heuchelheim -- Tel.: 0641/202360 • E-Mail: info-flow@digitaldata.works -- ================================================================= -- Creation Date / Author: 26.03.2025 / MK -- Version Date / Editor: 26.03.2025 / MK -- Version Number: 1.0.0.0 -- ================================================================= -- History: -- 26.03.2025 / MK - First Version CREATE OR ALTER PROCEDURE [dbo].[PRDD_GET_DB_DEADLOCKS]( pKILL_DEADLOCK_SESSIONS BIT = NULL ) AS BEGIN SET NOCOUNT ON; -- declare new vars because of parameter sniffing DECLARE @KILL_DEADLOCK_SESSIONS BIT = ISNULL(@pKILL_DEADLOCK_SESSIONS,0); DECLARE @DEADLOCK_SESSIONS TABLE ([GUID] [INT] IDENTITY(1,1) NOT NULL, [SessionID] [INT]) NOT NULL, [blocking_session_id] [INT] NOT NULL, [database_id] [INT] NOT NULL, [blocking_statement] [NVARCHAR](MAX) NULL, [blocked_statement] [NVARCHAR](MAX) NULL); -- declare runtime vars DECLARE @MyProcedureName NVARCHAR(128) = OBJECT_NAME(@@PROCID); DECLARE @GUID BIGINT, @SessionID INT, @blocking_session_id INT, @database_id INT, @blocking_statement NVARCHAR(MAX), @blocked_statement NVARCHAR(MAX), @return_status NVARCHAR(50) = 0, @return_status_text NVARCHAR(MAX) = 'START ' + @MyProcedureName + ' @ ' + CONVERT(varchar(50),GETDATE(),120); PRINT '===============================' PRINT 'PROCEDURE - ' + @return_status_text; PRINT 'PARAMETER01 - @KILL_DEADLOCK_SESSIONS: ' + CONVERT(VARCHAR(1),@KILL_DEADLOCK_SESSIONS); INSERT INTO @DEADLOCK_SESSIONS([SessionID],[blocking_session_id],[database_id],[blocking_statement],[blocked_statement]) WITH XMLNAMESPACES ('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS sp) SELECT [requests].[session_id], [requests].[blocking_session_id], [requests].[database_id], [sql_text1].[text] AS blocking_statement, [sql_text2].[text] AS blocked_statement FROM [master].[sys].[dm_exec_requests] as [requests] CROSS APPLY [master].[sys].[dm_exec_sql_text]([requests].[sql_handle]) [sql_text1] JOIN [master].[sys].[dm_exec_connections] as [connections] ON [requests].[blocking_session_id] = [connections].[session_id] CROSS APPLY [master].[sys].[dm_exec_sql_text]([connections].[most_recent_sql_handle]) [sql_text2] ORDER BY [requests].[database_id] ASC; SELECT * FROM @DEADLOCK_SESSIONS ORDER BY [SessionID]; SELECT [database_id], CONVERT(NVARCHAR(5), [session_id]) as 'SessionID', CONVERT(NVARCHAR(50), [login_name]) as 'LoginName', CONVERT(NVARCHAR(50), [host_name]) as 'HostName' FROM [master].[sys].[dm_exec_sessions] (NOLOCK) WHERE [is_user_process] = 1 AND [database_id] IN (SELECT DISTINCT [SessionID] FROM @DEADLOCK_SESSIONS ORDER BY [SessionID]); --==========================================-- Create the main loop (cursor) --============================================-- IF (SELECT COUNT(*) FROM @DEADLOCK_SESSIONS > 0) AND (@KILL_DEADLOCK_SESSIONS = 1) BEGIN DECLARE CURSOR_KILL_SESSIONS CURSOR STATIC LOCAL FOR SELECT [SessionID] FROM @DEADLOCK_SESSIONS; OPEN CURSOR_KILL_SESSIONS FETCH NEXT FROM CURSOR_KILL_SESSIONS INTO @SessionID WHILE @@FETCH_STATUS = 0 BEGIN BEGIN PRINT ' '; PRINT '-------------------------------'; PRINT 'Now processing: ' + CONVERT(varchar(100),@SessionID); KILL @SessionID ----------------------------------------------------------------------------------------------------------------------------- END; FETCH NEXT FROM CURSOR_KILL_SESSIONS INTO @SessionID; END; CLOSE CURSOR_KILL_SESSIONS; DEALLOCATE CURSOR_KILL_SESSIONS; END; ELSE BEGIN PRINT ''; PRINT 'There are no deadlocks, or deadlock kill is disabled!'; END;