У меня есть запрос SQL, который отлично работает вне хранимой процедуры. Когда я запускаю ее через хранимую процедуру, она просто запускается и никогда не завершается и, кажется, вызывает блокировки. Я делаю что-то просто неправильно, например, пропускаю NO LOCK в запросе sql cmd, или если есть что-то очевидное, я не вижу, что объясняет, почему эта хранимая процедура выполняется так долго и вызывает блокировку?
CREATE PROCEDURE [USP_GET_INACTIVE_REPORTS_EMAIL]
-- Author: XXXXXXXXX
-- Version 1.4 - Ready for Production ( LOL ! )
AS
BEGIN
set nocount on;
declare @trancount int;
set @trancount = @@trancount;
begin try
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
if @trancount = 0
begin transaction usp_get_inactive_reports_email;
else
save transaction usp_get_inactive_reports_email;
-- Step 1 - Create Temp Tables to hold Reporting DataSet for Active Reports that have not been executed in the last 30 days
IF OBJECT_ID('tempdb..##temp01') IS NOT NULL
BEGIN
DROP TABLE ##temp01
END
IF OBJECT_ID('tempdb..##temp02') IS NOT NULL
BEGIN
DROP TABLE ##temp02
END
-- Step 2 - Query the Report Server Catalog and Execution Log for answers . Active reports defined as not being hidden and having a description populated.
;WITH RankedReports AS
(
SELECT
ReportID,
TimeStart,
UserName,
RANK() OVER (PARTITION BY ReportID ORDER BY TimeStart DESC) AS iRank
FROM
ReportServer.dbo.ExecutionLog t1
JOIN
ReportServer.dbo.Catalog t2 ON t1.ReportID = t2.ItemID
AND t2.Type <> 1
)
SELECT DISTINCT
t1.UserName, t2.Name AS ReportName,
TimeStart,
SUBSTRING(t2.Path, 2, LEN(t2.Path) - LEN(t2.Name) - 1) AS Folder,
t2.Type
INTO ##temp01
FROM RankedReports t1
INNER JOIN ReportServer.dbo.Catalog t2 ON t1.ReportID = t2.ItemID
WHERE t1.iRank = 1
AND t2.Type <> 1
AND CAST(TimeStart AS DATE) > GETDATE() - 30
ORDER BY t1.UserName, t2.Name;
--- Select * from ##temp01 order by timestart
SELECT
cast ( SUBSTRING(Path,2,LEN(Path)-LEN(Name)-1) as varchar(100)) AS ReportFolder
,Name AS ReportName
,CreationDate
,ModifiedDate
,Type,replace([Description],'~','/') as Description,Hidden
INTO ##temp02
FROM ReportServer.dbo.Catalog
WHERE Name NOT IN (SELECT ReportName FROM ##temp01)
AND Path <> ''
AND SUBSTRING(Path,2,LEN(Path)-LEN(Name)-1)<>''
AND Description is not NULL
AND Type = 2 -- Means Report Type according to Mictosoft Docs for Report Server Schema
AND cast (ModifiedDate as date )<Getdate() - 30
OR (
Hidden='0' --- Reports that we have shown as hidden ad soft deletes done in SSRS
AND Name NOT IN (SELECT ReportName FROM ##temp01)
AND Path <> ''
AND SUBSTRING(Path,2,LEN(Path)-LEN(Name)-1)<>''
AND Type = 2 -- Means Report Type according to Mictosoft Docs for Report Server Schema)
AND cast (ModifiedDate as date )<Getdate() - 30
)
ORDER BY Path
-- Step 3 - If the Query return no results then dont email. If it does email it to requestforchange@creditfix.co.uk
declare @counter int
;with query as (
SELECT ReportFolder
,ReportName
,CreationDate
,ModifiedDate
,Type,[Description],Hidden
FROM ##temp02 where Hidden=0 AND Description is not null
)
select @counter = count(*) from query
--- Step 4 - If the count of rows from Inactive Reports query >0 then Send the email about which reports to xxxxx
IF @counter > 0
BEGIN
--execute xp_cmdshell 'bcp "SELECT '' ReportFolder,ReportName,CreationDate,ModifiedDate,Type,Description FROM ##temp02 WHERE ReportFolder <>''''AND Description is not NULL AND Type = 2 AND Hidden=0 ORDER BY 4" queryout C:\xxxxx\BI_Active_Reports_not_used_in_Last_30_days.csv -c -t, -S xxxxxx -U xxxxx -P xxxxxxx'
declare @fileNameTXT varchar(200) = '\\xxxxxx\Active_Reports_not_used_in_Last_30_days.csv'
declare @sql_bcp varchar(1000) = 'sqlcmd -S xxxxx -d xxxxxx Rep -E -Q "set nocount on; PRINT ''Reportname'' + '','' + ''ReportFolder'' ;SELECT ReportName,ReportFolder FROM ##temp02 where Hidden=0 AND Description is not null " -o ' + @filenameTXT + ' -W -h -1 -s"," -w 1500'
--print @sql_bcp
execute xp_cmdshell @sql_bcp
--- Send Email Section to export query contents to a CSV Output File
EXEC msdb.dbo.sp_send_dbmail
@profile_name = 'SMTP Server Mail',
@recipients= 'xxxxxx',
@subject = 'IT - Active Reports not used in the Last 30 days',
@execute_query_database = 'ReportServer',
@body = 'Greetings, <br><br>
Please find attached Reports that have not been run in the last 30 days.
<br><br>
Kind Regards
<br><br>
xxxxxx Team',
@body_format = 'HTML',
@file_attachments= '\\xxxxx\Active_Reports_not_used_in_Last_30_days.csv'
commit transaction usp_get_inactive_reports_email
END
ELSE
BEGIN
--RAISERROR('No rows exist, quit job', 16, 1);
commit transaction usp_get_inactive_reports_email;
--print 'commit'
Return;
END
commit transaction usp_get_inactive_reports_email;
end try
begin catch
declare @error int, @message varchar(4000), @xstate int;
select @error = ERROR_NUMBER(), @message = ERROR_MESSAGE(), @xstate = XACT_STATE();
if @xstate = -1
rollback;
if @xstate = 1 and @trancount = 0
rollback
if @xstate = 1 and @trancount > 0
rollback ;
raiserror ('usp_get_inactive_reports_email: %d: %s', 16, 1, @error, @message) ;
return;
end catch
end