Olivier Jooris posted on mei 21, 2009 09:19
De oplossing is eenvoudig: maak gebruik van een TRANSACTION en een TRY-CATCH blok:
|
ALTER PROCEDURE [dbo].[gl_modify_claim_status_preclaim]
@claimid int,
@claimstatus nvarchar(5),
@fitstationid int,
@inscompanyid int,
@userid int
AS
set nocount on;
DECLARE @err nvarchar(255);
-- make a logical unit of work (LUW)
BEGIN TRY
begin transaction tpreclaim
-- check for correct claimstatus
if not ( @claimstatus = 'P0' or @claimstatus = 'P1' or @claimstatus = 'P2' or @claimstatus = 'P3' or @claimstatus = 'A0')
RAISERROR('Invalid pre-claimstatus code: %s',11,5,@claimstatus)
-- update the status
update gl_claims
set claimstatus = @claimstatus
, dt_upd = getdate()
where claimid = @claimid;
-- check result
if @@rowcount <> 1
RAISERROR('Could not find pre-claim',11,5 )
-- log the update
EXEC [dbo].[gl_logAdd] @what = N'pre-claim statuschange',@who = @userid,@fitstatid = @fitstationid,@external_fit = 1,
@inscompanyid = @inscompanyid , @claimid = @claimid,@invoicenr = 0,@extra = N'',@newstat = @claimstatus;
-- commit the actions
COMMIT TRANSACTION tpreclaim;
-- return result
select 0
END TRY
BEGIN CATCH
set @err = ERROR_MESSAGE()
ROLLBACK TRANSACTION tpreclaim
RAISERROR('Unexpected error on update pre-claim: %i, reason: %s',11,5,@claimid ,@err )
END CATCH
|
Alles wat binnen een BEGIN TRANSACTION en een COMMIT TRANSACTION wordt uitgevoerd, blijft als 1 logisch geheel.
Dus als er een fout optreed in het midden van de updates dan wordt alles wat reeds gewijzigd is teruggedraaid tot de situatie voor dat de BEGIN TRANSACTION werd uitgevoerd.
De TRY-CATCH blok zorgt hiervoor, als er een fout optreed wordt onmiddelijk het BEGIN CATCH blok uitgevoerd, waar de TRANSACTION ROLLBACK staat die alles naar zijn oorspronkelijke staat terug brengt.
Het programma merkt dan het probleem om en krijgt een duidelijke foutboodschap dank zij de RAISERROR statement.