寻求退出循环的帮助
Looking for help exiting out of loop
我一直在努力复制 AutoSys 的 Box 功能。我遇到了此处显示的解决方案 (https://dba.stackexchange.com/a/161658),它非常非常有效。我开始添加它,检查结果,并添加我们使用的另一个 ETL 解决方案的处理。
我 运行 遇到麻烦的地方是,当我意识到没有检查工作是否有效时。我想检查一下,以防工作名称拼写错误,或者有人删除了工作。如果没有,我不想假设正在执行一项工作。我添加了对有效 SQL 代理作业名称的检查。如果作业名称有效,则此方法有效。但是,如果作业名称无效,该过程将陷入循环并显示错误消息 'NO JOB',直到我停止该过程。
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,结束该轮,转到下一个作业。
我不明白为什么它会卡在循环中。
感谢您的帮助。
由于您的循环很长且包含嵌套块且难以调试,我将执行以下操作:
- 在进入循环之前,验证缺少哪些作业
- 创建一个 table 来保存丢失的工作,例如@MissingJobs,在你处理现有工作之前用它们做你的事情
- 基于@MissingJobs 从@JobList table 中删除缺失的作业,然后循环遍历这些作业,因此在这种情况下无需调试长循环块。或者创建一个新的 table 如果您需要原始文件并在循环中使用它 - 但在这种情况下,需要做更多的工作才能从 @JobList 更改为新文件。如果将所有减少的@JobList 与@MissingJobs 联合,您可以取回原始列表。无论如何,您需要删除 --VALID JOB 之后的块? (直到 PRINT 'YES WE FOUND THE JOB';)因为你可以根据这个逻辑打印出来 - 在这种情况下你还必须在 SET @JobNumber = @JobNumber + 1; 之后删除一个 END;因为你删除了一个未关闭的 ELSE BEGIN。
我一直在努力复制 AutoSys 的 Box 功能。我遇到了此处显示的解决方案 (https://dba.stackexchange.com/a/161658),它非常非常有效。我开始添加它,检查结果,并添加我们使用的另一个 ETL 解决方案的处理。
我 运行 遇到麻烦的地方是,当我意识到没有检查工作是否有效时。我想检查一下,以防工作名称拼写错误,或者有人删除了工作。如果没有,我不想假设正在执行一项工作。我添加了对有效 SQL 代理作业名称的检查。如果作业名称有效,则此方法有效。但是,如果作业名称无效,该过程将陷入循环并显示错误消息 'NO JOB',直到我停止该过程。
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,结束该轮,转到下一个作业。
我不明白为什么它会卡在循环中。 感谢您的帮助。
由于您的循环很长且包含嵌套块且难以调试,我将执行以下操作:
- 在进入循环之前,验证缺少哪些作业
- 创建一个 table 来保存丢失的工作,例如@MissingJobs,在你处理现有工作之前用它们做你的事情
- 基于@MissingJobs 从@JobList table 中删除缺失的作业,然后循环遍历这些作业,因此在这种情况下无需调试长循环块。或者创建一个新的 table 如果您需要原始文件并在循环中使用它 - 但在这种情况下,需要做更多的工作才能从 @JobList 更改为新文件。如果将所有减少的@JobList 与@MissingJobs 联合,您可以取回原始列表。无论如何,您需要删除 --VALID JOB 之后的块? (直到 PRINT 'YES WE FOUND THE JOB';)因为你可以根据这个逻辑打印出来 - 在这种情况下你还必须在 SET @JobNumber = @JobNumber + 1; 之后删除一个 END;因为你删除了一个未关闭的 ELSE BEGIN。