Por que, quando estou SAVE TRAN SavePoint
no local (A), recebo esses erros na terceira instância de cair no CATCH e além...
"Msg 6401, Nível 16, Estado 1... Não é possível reverter o SavePoint. Nenhuma transação ou ponto de salvamento com esse nome foi encontrado."
...mas não recebo esses erros quando SAVE TRAN SavePoint;
estou no local (B)?
Só posso imaginar que tenha algo a ver com o contexto do loop do cursor, mas não entendo por quê.
-- Premable stuff, opening cursor, etc. here...
BEGIN TRAN
SAVE TRAN SavePoint; -- (A)
WHILE @@FETCH_STATUS = 0
BEGIN;
-- SAVE TRAN SavePoint; -- (B)
BEGIN TRY
-- UPDATE statement here which may fail
SAVE TRAN SavePoint;
END TRY
BEGIN CATCH
ROLLBACK TRAN SavePoint;
END CATCH;
FETCH NEXT FROM Cursor INTO @X, @Y, @Z;
END;
-- CLOSE & DEALLOCATE stuff here
IF @DryRun = 1
ROLLBACK TRAN;
ELSE
COMMIT TRAN;
Quando você reverte para um ponto de salvamento, esse ponto de salvamento é esgotado.
Na posição A, você define apenas uma vez, portanto só pode ser usado uma vez.
Você tem permissão para definir um ponto de salvamento com o mesmo nome mais de uma vez.
Ao fazer isso na posição B, você garante que ela estará disponível em todas as iterações do loop.
O comportamento é um pouco estranho e os pontos de salvamento não são amplamente utilizados por vários motivos .
Isso imprime seu erro:
Isso não causa um erro:
Curiosamente, isso também não acontece: