Вы пробовали отладку / вывод того, что на самом деле происходит при запуске процедуры? Например, можете ли вы изменить свой @killstatement так, чтобы он был объявлен как nvarchar (max), и включили несколько подробных выводов, таких как приведенные ниже, и опубликовали результаты? В основном замените все в вашем блоке начала / конца на что-то вроде:
-- Construct dynamic sql to kill spid
select @killstatement = N'
select *
from sys.dm_exec_sessions s
join sys.dm_exec_connections c
on s.session_id = c.session_id
where c.session_id = @spid;
kill ' + cast(@spid as varchar(3)) + ';
select *
from sys.dm_exec_sessions s
join sys.dm_exec_connections c
on s.session_id = c.session_id
where c.session_id = @spid;
';
-- Print & Exec
print @killstatement;
exec sp_executesql @killstatement, N'@spid smallint', @spid;
print @spid;
Нет причин, по которым что-то должно вести себя по-другому в коде процедуры по сравнению с явным выполнением в соединении - при условии, что у вас есть соответствующие разрешения, вы убиваете допустимые спиды и т. Д., И т. Д. Если вы можете опубликовать результаты некоторой отладки, например выше (и все, что вы, возможно, пытались), это поможет выяснить, где проблема. Возможно, вы также захотите включить отладочный вывод результатов объявления курсора, который вы используете, чтобы убедиться, что вы фактически получаете сеансы, которые вы пытаетесь уничтожить - т.е. просто включите тот же выбор, который вы используете в объявлении курсора, чтобы вывести набор результатов, например:
declare c1 cursor for select request_session_id
from sys.dm_tran_locks
where resource_type='DATABASE'
AND DB_NAME(resource_database_id) = @database
-- Debug output - sessions we should try and kill...
select request_session_id
from sys.dm_tran_locks
where resource_type='DATABASE'
AND DB_NAME(resource_database_id) = @database;
Если вы сможете опубликовать результаты, надеюсь, это даст нам возможность продолжить.