Я работаю над тем, чтобы воспроизвести функцию Box в AutoSys. Я наткнулся на показанное здесь решение (https://dba.stackexchange.com/a/161658),, которое работает очень и очень хорошо. Я начал добавлять к нему, проверять результат и добавлять обработку другого решения ETL, которое мы используем.
Когда я столкнулся с проблемой, это когда я понял, что ничто не проверяет, была ли работа приемлемой. Я хочу проверить это в случае, если имя работы написано неправильно, или если кто-то удаляет работу. Я не хочу предполагать, что работа выполняется, если это не так. Я добавил проверку правильности имени задания агента SQL. Это работает, если имена заданий действительны. Однако, если имя задания недопустимо, процедура застревает в цикле, отображая сообщение об ошибке «НЕТ ЗАДАНИЯ», пока я не остановлю процедуру.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[usp_start_job_sequence8]
(
@JobList JobSequenceTable READONLY
,@PrntJob VARCHAR(100) = 'Unknown_Job'
)
AS
BEGIN
SET NOCOUNT ON;
SET XACT_ABORT ON;
SET QUOTED_IDENTIFIER ON;
SET ANSI_NULLS ON;
SET ANSI_PADDING ON;
SET ARITHABORT ON;
SET CONCAT_NULL_YIELDS_NULL ON;
SET NUMERIC_ROUNDABORT OFF;
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SET ANSI_WARNINGS OFF;
---------------------************TRY BLOCK************---------------------
BEGIN TRY
BEGIN
DECLARE
@JobNumber TINYINT = 1
,@JobName VARCHAR(100)
,@IsRunning BIT
,@IsEnabled BIT
,@JOB_ID VARCHAR(60) = NULL
,@JOB_HIST_ID INT
,@JOB_STATUS VARCHAR(30)
,@JOB_STATUS_ID INT
,@esub VARCHAR(100)
,@ebdy VARCHAR(500)
,@Envt VARCHAR(4)
,@OVJOB_ID VARCHAR(60)
,@OVJOB_NAME VARCHAR(120)
,@JOB_TYPE CHAR(3)
,@epri VARCHAR(6);
--- Set server environment for emails
SELECT
@Envt = CASE WHEN @@SERVERNAME LIKE '%D%' THEN 'Dev'
WHEN @@SERVERNAME LIKE '%U%' THEN 'UAT'
WHEN @@SERVERNAME LIKE '%P%' THEN 'Prod'
WHEN @@SERVERNAME LIKE '%R%' THEN 'BCP'
ELSE ''
END
--- Set server environment for email priority
,@epri = CASE WHEN @@SERVERNAME LIKE '%D%' THEN 'Low'
WHEN @@SERVERNAME LIKE '%U%' THEN 'Normal'
WHEN @@SERVERNAME LIKE '%P%' THEN 'High'
WHEN @@SERVERNAME LIKE '%R%' THEN 'High'
ELSE ''
END;
BEGIN
WHILE (@JobNumber <= (SELECT
MAX(JobNumber)
FROM
@JobList
))
BEGIN
SELECT
@JobName = JobName
FROM
@JobList
WHERE
JobNumber = @JobNumber;
--VALID JOB?
IF NOT EXISTS(SELECT j.name FROM msdb.dbo.sysjobs_view J WITH(NOLOCK)
WHERE j.Name = @JobName)
BEGIN
PRINT 'NO JOB'
END;
ELSE
BEGIN
PRINT 'YES WE FOUND THE JOB';
--END
SELECT
@JOB_ID = job_id
FROM
msdb.dbo.sysjobs_view
WHERE
name = @JobName;
SELECT
@IsEnabled = enabled
FROM
msdb.dbo.sysjobs_view
WHERE
name = @JobName;
--- Very important step here. Ouvvi job names must start with Ouvvi
SELECT
@JOB_TYPE = CASE WHEN @JobName LIKE 'Ouvvi%'
THEN 'OVI'
ELSE 'SQL'
END;
--- Check if the job already running
SELECT
@IsRunning = dbo.fnJobStatusCheck(@JobName);
IF @IsRunning = 0
BEGIN
IF @IsEnabled = 0 --- Job is disabled error and send email
BEGIN
PRINT 'Job ' + @JobName
+ ' is disabled and cannot be started';
SET @esub = 'SQL Agent job '
+ @JobName + ' in ' + @Envt
+ ' is disabled and cannot be started';
SET @ebdy = 'SQL Agent job '
+ @JobName
+ ' was scheduled to run in box job '
+ @PrntJob + ' on server '
+ @@SERVERNAME + '. '
+ @JobName
+ ' could not start as it is disabled.'
+ CHAR(10) + CHAR(13)
+ +'The job ' + @JobName
+ ' should either be enabled, or removed from box job '
+ @PrntJob + '.';
EXEC msdb.dbo.sp_send_dbmail
--@profile_name = '',
-- @recipients = 'group@mail.com'
@recipients = 'person@mail.com',
@importance = @epri,
@subject = @esub,@body = @ebdy;
END;
ELSE ---- @IsEnabled = 1
----- Job is not running nor disabled. Split for different types
---OUVVI
BEGIN
IF @JOB_TYPE = 'OVI'
BEGIN
--PRINT 'OUVVI JOB'; --- TESTING
--- Parse Ouvvi Project ID - Used for success-failure
SET @OVJOB_ID = (SELECT
RTRIM(SUBSTRING(command,
CHARINDEX('/start/',
command) + 7,3))
FROM
msdb.dbo.sysjobsteps
WHERE
job_id = @JOB_ID
AND step_id = 1
);
--- START Ouvvi Job
EXEC msdb.dbo.sp_start_job @job_name = @JobName;
--PRINT @OVJOB_ID; --- TESTING
-- Waiting for the job to finish - Ouvvi jobs don't start immediately
WAITFOR DELAY '00:00:01';
WHILE (SELECT
1
FROM
Ouvvi.dbo.Queue
WHERE
ProjectID = @OVJOB_ID
) IS NOT NULL
BEGIN
WAITFOR DELAY '00:00:15';
IF (SELECT
1
FROM
Ouvvi.dbo.Queue
WHERE
ProjectID = @OVJOB_ID
) IS NULL
BREAK;
END;
--- Get Ouvvi Job Hist ID
SET @JOB_HIST_ID = (SELECT
Instance.ID
FROM
Ouvvi.dbo.Instance
WHERE
Instance.ProjectID = @OVJOB_ID
AND Instance.EndTime = (SELECT
MAX(EndTime)
FROM
Ouvvi.dbo.Instance
WHERE
Instance.ProjectID = @OVJOB_ID
)
);
--- Get Ouvvi Result
SET @JOB_STATUS_ID = (SELECT
ISNULL(I.Result,
9)
FROM
Ouvvi.dbo.Instance I
WHERE
I.ID = @JOB_HIST_ID
);
SET @JOB_STATUS = (SELECT
CASE
WHEN I.Result = 1
THEN 'Succeeded'
WHEN I.Result = 2
THEN 'Failed'
WHEN I.Result = 3
THEN 'Cancelled'
ELSE 'Unknown'
END
FROM
Ouvvi.dbo.Instance I
WHERE
I.ID = @JOB_HIST_ID
);
IF @JOB_STATUS_ID <> 1
BEGIN
PRINT @JobName
+ ' erred with the following status: '
+ @JOB_STATUS;
SET @esub = 'Ouvvi SQL Agent job '
+ @JobName
+ ' in ' + @Envt
+ ' erred with the following status: '
+ @JOB_STATUS;
SET @ebdy = 'An Ouvvi job, scheduled in SQL Agent '
+ @JobName
+ ' has erred with the following status: '
+ @JOB_STATUS
+ ' on server '
+ @@SERVERNAME
+ '.';
EXEC msdb.dbo.sp_send_dbmail
--@profile_name = '',
-- @recipients = 'group@mail.com'
@recipients = 'person@mail.com',
@importance = @epri,
@subject = @esub,
@body = @ebdy;
END;
END;
----Its a SQL Server Job
ELSE
BEGIN
EXEC msdb.dbo.sp_start_job @job_name = @JobName;
END;
WAITFOR DELAY '00:00:15.000';
SELECT
@IsRunning = dbo.fnJobStatusCheck(@JobName);
WHILE @IsRunning = 1
BEGIN
WAITFOR DELAY '00:00:15.000';
SELECT
@IsRunning = dbo.fnJobStatusCheck(@JobName);
END;
BEGIN
SET @JOB_HIST_ID = (SELECT
job_history_id
FROM
msdb.dbo.sysjobactivity
WHERE
job_id = @JOB_ID
AND run_requested_date = (SELECT
MAX(run_requested_date)
FROM
msdb.dbo.sysjobactivity
WHERE
job_id = @JOB_ID
)
);
SET @JOB_STATUS_ID = (SELECT
ISNULL(run_status,
9)
FROM
msdb.dbo.sysjobhistory
WHERE
instance_id = @JOB_HIST_ID
);
SET @JOB_STATUS = (SELECT
CASE
WHEN @JOB_STATUS_ID = 0
THEN 'Failed'
WHEN @JOB_STATUS_ID = 1
THEN 'Succeeded'
WHEN @JOB_STATUS_ID = 2
THEN 'Retry'
WHEN @JOB_STATUS_ID = 3
THEN 'Cancelled'
ELSE 'Unknown'
END
);
BEGIN
IF @JOB_STATUS_ID <> 1
BEGIN
PRINT @JobName
+ ' erred with the following status: '
+ @JOB_STATUS;
SET @esub = 'SQL Agent job '
+ @JobName
+ ' in ' + @Envt
+ ' erred with the following status: '
+ @JOB_STATUS;
SET @ebdy = 'SQL Agent job '
+ @JobName
+ ' erred with the following status: '
+ @JOB_STATUS
+ ' on server '
+ @@SERVERNAME
+ '.';
EXEC msdb.dbo.sp_send_dbmail
--@profile_name = '',
-- @recipients = 'group@mail.com'
@recipients = 'person@mail.com',
@importance = @epri,
@subject = @esub,
@body = @ebdy;
END;
END;
END;
END;
SET @JOB_ID = NULL;
SET @JobNumber = @JobNumber + 1;
END;
END;
END;
END;
END;
END TRY
---------------------*********************************--------------------
---------------------************CATCH BLOCK**********-------------------
BEGIN CATCH
-- Print Error Information
DECLARE @ERRORMESSAGE NVARCHAR(4000);
DECLARE @ERRORSEVERITY INT;
DECLARE @ERRORSTATE INT;
SELECT
@ERRORMESSAGE = ERROR_MESSAGE()
,@ERRORSEVERITY = ERROR_SEVERITY()
,@ERRORSTATE = ERROR_STATE();
RAISERROR (@ERRORMESSAGE, @ERRORSEVERITY, @ERRORSTATE);
-- Rollback uncommittable transactions
IF (XACT_STATE()) = -1
BEGIN
PRINT 'The transaction is in an uncommittable state.'
+ ' Rolling back transaction.';
ROLLBACK TRANSACTION;
END;
-- Inserting error related information into the Error Log table
INSERT INTO dbo.tbl_Object_ErrorLog
(ObjectName
,ErrorNumber
,ErrorMessage
,ErrorSeverity
,ErrorState
,ErrorlINE
,SystemUser
,LogDate
)
SELECT
ERROR_PROCEDURE()
,ERROR_NUMBER()
,ERROR_MESSAGE()
,ERROR_SEVERITY()
,ERROR_STATE()
,ERROR_LINE()
,SYSTEM_USER
,GETDATE();
END CATCH;
---------------------********************************----------------------
END;
GO
Код для запуска процедуры:
SET ANSI_WARNINGS OFF
GO
DECLARE @JobList AS JobSequenceTable
INSERT INTO @JobList
VALUES
('x_test3')
,('NoJobHere')
,('x_test1')
EXEC dba.dbo.usp_start_job_sequence8 @JobList, 'TESTING'
Я хочу, чтобы это произошло: когда он проверяет правильное имя задания, печатает NO JOB и завершает работу, он должен перейти к строке 378, добавить 1 к @JobNumber, завершить этот раунд и перейти к следующему заданию.
Я не могу понять, почему он застрял в петле.
Спасибо за любую помощь.