Hi guys,Trying to get some opinions on errorhandling in SPs, and neatness/code structure. We are using .Net.--sample table and datacreate table TestDel(loginId int identity(1,1),val int)goinsert into testdel (val)select 1 union all select 2 union all select 3select * from testdel
An SP using multi-returnsif exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[up_testdel]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)drop procedure [dbo].[up_testdel]GO SET QUOTED_IDENTIFIER OFF SET ANSI_NULLS OFF SET NOCOUNT ONGOCREATE PROCEDURE up_testdel(@LoginID int) ASSET NOCOUNT ONSET TRANSACTION ISOLATION LEVEL READ COMMITTED DECLARE @Error INTEGER --capture @@errorDECLARE @RowCount INTEGER --capture @@rowcount--DECLARE @ReturnResult INTEGER --capture return value to hand back--If we can use RaiseError:-- DECLARE @DatabaseId INT-- SET @DatabaseId = DB_ID()-- -- DECLARE @DatabaseName NVARCHAR(128)-- SET @DatabaseName = DB_NAME()--We COULD consider adding "design by contract" by checking for valid value and number of rows returned,-- i.e. select @ContractCheckLoginId = count(*) from dbo.TestDel-- if @ContractCheckLoginId <> 1 the fail-- but we don't have defined way of enabling atm the moment.BEGIN TRANSACTION --unless you handle this outsideDELETE FROM dbo.TestDel WHERE Loginid = @LoginIDSELECT @RowCount=@@rowcount,@Error = @@errorIF @Error <> 0 -- Can we handle RaiseError messages? BEGIN ROLLBACK TRANSACTION --remove if transaction handled outside. NB then to use RETURN value to ensure rollback -- RAISERROR ('Error deleting from table TestDel - rolled rack transaction',16,1,@DatabaseId,@DatabaseName) RETURN -1 --Use -1 to indicate serious error processing SQLENDIF @RowCount <> 1 BEGIN ROLLBACK TRANSACTION --remove if transaction handled outside. NB then to use RETURN value to ensure rollback -- RAISERROR ('Incorrect number of rows deleted - rolled rack transaction',16,1,@DatabaseId,@DatabaseName) RETURN -2 --Use -2 to indicate incorrect number of rows affected. Breach of contract effectively. END ELSE COMMIT TRANSACTION --remove if transaction handled outside. NB then to use RETURN value to ensure rollbackRETURN 0GOOr a goto structured SP:if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[up_testdel2]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)drop procedure [dbo].[up_testdel2]GO SET QUOTED_IDENTIFIER OFF SET ANSI_NULLS OFF SET NOCOUNT ONGOCREATE PROCEDURE up_testdel2(@LoginID int) ASSET NOCOUNT ONSET TRANSACTION ISOLATION LEVEL READ COMMITTED DECLARE @Error INTEGER --capture @@errorDECLARE @RowCount INTEGER --capture @@rowcountDECLARE @ReturnResult INTEGER --capture return value to hand back--If we can use RaiseError:-- DECLARE @DatabaseId INT-- SET @DatabaseId = DB_ID()-- -- DECLARE @DatabaseName NVARCHAR(128)-- SET @DatabaseName = DB_NAME()--We COULD consider adding "design by contract" by checking for valid value and number of rows returned,-- i.e. select @ContractCheckLoginId = count(*) from dbo.TestDel-- if @ContractCheckLoginId <> 1 the fail-- but we don't have defined way of enabling atm the moment.BEGIN TRANSACTION --unless you handle this outsideDELETE FROM dbo.TestDel WHERE Loginid = @LoginIDSELECT @RowCount=@@rowcount,@Error = @@errorIF (@Error = 0 and @RowCount = 1) Begin SET @ReturnResult = 0 COMMIT TRANSACTION GOTO ReturnResultENDIF @Error <> 0 -- Can we handle RaiseError messages? BEGIN ROLLBACK TRANSACTION --remove if transaction handled outside. NB then to use RETURN value to ensure rollback -- RAISERROR ('Error deleting from table TestDel - rolled rack transaction',16,1,@DatabaseId,@DatabaseName) SET @ReturnResult = @Error--Use -1 to indicate serious error processing SQL GOTO ReturnResultENDIF @RowCount <> 1 BEGIN ROLLBACK TRANSACTION --remove if transaction handled outside. NB then to use RETURN value to ensure rollback -- RAISERROR ('Incorrect number of rows deleted - rolled rack transaction',16,1,@DatabaseId,@DatabaseName) SET @ReturnResult = -2 --Use -2 to indicate incorrect number of rows affected. Breach of contract effectively. GOTO ReturnResultENDReturnResult:RETURN @ReturnResultGOTest:[]set nocount onDECLARE @lg intDECLARE @Rc intset @lg = 4exec @rc=up_testdel @lgselect @rcexec @rc=up_testdel2 @lgselect @rcset @lg = 2exec @rc=up_testdel @lgselect @rcexec @rc=up_testdel2 @lgselect @rc[/]opinions on the better method of returning to caller the return?opinions on the use of RaiseError?CiaO*##* *##* *##* *##* Chaos, Disorder and Panic ... my work is done here!