I have a stored procedure that is run by the SQL Agent every x minutes. The stored procedure has a while loop that reads each row and does something with them.
I want to handle errors as they occur in the while loop. I need to use Throw
in the CATCH
block because then SQL Server Agent will not notify if an error occurred.
But the problem is if I use the throw block it breaks out of the while loop but does not process the other records.
How can I use TRY CATCH
in a while loop and if an error occurs it should continue with while loop?
This is my code:
WHILE @i<@Count OR @Count IS NULL
BEGIN
SELECT @Id = NULL --Clear variable
SELECT TOP 1
@Id = Id,
@TableNo = [TableNo],
@Action = [Action],
@RecId = [RecId],
@NDB = dbo.GetDB(CId)
FROM
dbo.alot WITH (NOLOCK)
WHERE
CId = @Cid
AND Error = 0
AND (@Table IS NULL OR TableNo = @Table)
AND Tableno <> 50109
ORDER BY
Id
IF @Id IS NOT NULL
BEGIN
SELECT
@SQL = N'EXECUTE @RC = ['+dbo.GetDB(@CId)+'].[dbo].[alot_web] @TableNo, @Action, @RecId, @NaviDB'
BEGIN TRY
IF @RecId = '0-761345-27353-4'
BEGIN
SELECT 1 / 0; -- Generate an error here.
END
EXEC master.dbo.sp_executesql @SQL, N'@TableNo nvarchar(12), @Action tinyint, @RecId nvarchar(36), @NDB varchar(12), @RC int OUTPUT'
, @TableNo, @Action, @RecId, @NaviDB, @Rc OUTPUT
END TRY
BEGIN CATCH
DECLARE @Description VARCHAR(1024);
SELECT @Description = 'WebQueue ID: ' + ISNULL(CAST(@Id AS VARCHAR), '') + ' CompanyID: ' + ISNULL(@Cid, '') + ' Action: ' + ISNULL(CAST(@Action AS VARCHAR), '') + ' RecID: ' + ISNULL(CAST(@RecId AS VARCHAR), '') + ' @RC: ' + ISNULL(CAST(@RC AS VARCHAR), '');
EXEC dbo.LogError @Description;
THROW;
END CATCH
IF @RC = 0 AND @@ERROR = 0
BEGIN
IF EXISTS(SELECT * FROM Queue
WHERE CId = @CId AND [Action] = @Action
AND TableNo = @Tableno AND RecId = @RecID AND Id <> @Id)
BEGIN
DELETE FROM Queue
WHERE CId = @CId AND [Action] = @Action AND TableNo = @Tableno
AND RecId = @RecID
SELECT @Ok += @@ROWCOUNT
END
ELSE BEGIN
DELETE FROM Queue WHERE Id = @Id
SELECT @Ok += @@ROWCOUNT
END
END
ELSE BEGIN
IF EXISTS(SELECT * FROM Queue
WHERE CId = @CId AND [Action] = @Action
AND TableNo = @Tableno AND RecId = @RecID AND Id <> @Id)
BEGIN
UPDATE Queue
SET Error = 1
WHERE CId = @CId AND [Action] = @Action AND TableNo = @Tableno AND RecId = @RecID
SELECT @Failed += @@ROWCOUNT
END
ELSE BEGIN
UPDATE Queue
SET Error = 1
WHERE Id = @Id
SELECT @Failed += @@ROWCOUNT
END
END
END
ELSE
BREAK
SELECT @i += 1
/*IF @i>0 BEGIN--logging >>
INSERT INTO [AdminDB].[dbo].[Replication_Log] ([Date],[CId],[Loops],[DurationSS],[Ok],[Failed])
SELECT Getdate(),@CId,@i,DATEDIFF(ss,@Startdt,getdate()),@Ok,@Failed
END */
END