I quickly scanned the posted code. The problem is that the layout is like this:
WHILE (condition)
BEGIN;
BEGIN TRY
-- Do something that might fail
-- Find next row to process
END TRY
BEGIN CATCH
-- Handle error
END CATCH
END; -- Ends while loop
If you get a failure, control passes to the CATCH block. So the last part of the TRY block, where the next row is read, is never reached.
Try rearranging like this:
WHILE (condition)
BEGIN;
BEGIN TRY
-- Do something that might fail
END TRY
BEGIN CATCH
-- Handle error
END CATCH
-- Find next row to process
END; -- Ends while loop