Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2008 Forums
 Transact-SQL (2008)
 Help adding Try Catch to exsting script

Author  Topic 

Eagle_f90
Constraint Violating Yak Guru

424 Posts

Posted - 2012-04-11 : 19:30:02
I am trying to convert an existing SQL script to have a try catch error system. Can anyone look it over and make sure I did it right? This SP will be called by other SPs to it is important to return to the calling script that an error happened so when I convert that one to try catch it will error out also.

Original Script:
CREATE PROC dbo.spAddSectionMenuItem
@SectionID AS smallint,
@MenuType AS char(5),
@LinkRoute AS varchar(50),
@LinkName AS varchar(50),
@LinkTitle AS varchar(250)
AS

SET NOCOUNT ON
SET XACT_ABORT ON

DECLARE @ErrorNum int

BEGIN TRANSACTION

IF NOT EXISTS (SELECT 1 FROM dbo.SectionMenuItems WHERE SectionID = @SectionID and MenuType = @MenuType)
BEGIN
INSERT INTO dbo.SectionMenuItems (SectionID, MenuType, LinkRoute, LinkName, LinkTitle)
VALUES (@SectionID, @MenuType, @LinkRoute, @LinkName, @LinkTitle);

SET @ErrorNum = @@ERROR;
END

if (@ErrorNum = 0)
BEGIN
COMMIT
END
ELSE
BEGIN
ROLLBACK
END

RETURN @ErrorNum


New script:
CREATE PROC dbo.spAddSectionMenuItem
@SectionID AS smallint,
@MenuType AS char(5),
@LinkRoute AS varchar(50),
@LinkName AS varchar(50),
@LinkTitle AS varchar(250)
AS

SET NOCOUNT ON
SET XACT_ABORT ON

DECLARE @ErrorNum int

BEGIN TRY
BEGIN TRANSACTION

IF NOT EXISTS (SELECT 1 FROM dbo.SectionMenuItems WHERE SectionID = @SectionID and MenuType = @MenuType)
BEGIN
INSERT INTO dbo.SectionMenuItems (SectionID, MenuType, LinkRoute, LinkName, LinkTitle)
VALUES (@SectionID, @MenuType, @LinkRoute, @LinkName, @LinkTitle);

RETURN 0;
END

COMMIT
END TRY

BEGIN CATCH
RETURN @@ERROR;

ROLLBACK
END CATCH


--
If I get used to envying others...
Those things about my self I pride will slowly fade away.
-Stellvia

sunitabeck
Master Smack Fu Yak Hacker

5155 Posts

Posted - 2012-04-11 : 20:44:53
In your catch block you are returning before you roll back - that is not what you want to do. What you want to do is something along these lines - I only wrote this, did not test:
CREATE PROC dbo.spAddSectionMenuItem
@SectionID AS SMALLINT,
@MenuType AS CHAR(5),
@LinkRoute AS VARCHAR(50),
@LinkName AS VARCHAR(50),
@LinkTitle AS VARCHAR(250)
AS

SET NOCOUNT ON
SET XACT_ABORT ON

DECLARE @ErrorNum int
BEGIN TRY
BEGIN TRAN

IF NOT EXISTS (SELECT 1 FROM dbo.SectionMenuItems WHERE SectionID = @SectionID and MenuType = @MenuType)
BEGIN
INSERT INTO dbo.SectionMenuItems (SectionID, MenuType, LinkRoute, LinkName, LinkTitle)
VALUES (@SectionID, @MenuType, @LinkRoute, @LinkName, @LinkTitle);

RETURN 0;
END

COMMIT
SET @ErrorNum = 0;

END TRY
BEGIN CATCH
IF (XACT_STATE()) = -1
BEGIN
ROLLBACK TRAN; -- cannot commit, you can only roll back
END
ELSE IF (XACT_STATE()) = 1
BEGIN
COMMIT TRAN; -- You can commit, but you can roll back if you choose to.
END
-- else nothing to commit
SET @ErrorNum = 1;
END CATCH
RETURN @ErrorNum;
Go to Top of Page

Eagle_f90
Constraint Violating Yak Guru

424 Posts

Posted - 2012-04-11 : 21:10:33
With using the RETURN @ErrorNum how would I deal with that in the procs that call this one? I want to make sure if this one fails it fails the master too

--
If I get used to envying others...
Those things about my self I pride will slowly fade away.
-Stellvia
Go to Top of Page

sunitabeck
Master Smack Fu Yak Hacker

5155 Posts

Posted - 2012-04-12 : 07:34:20
If you want to nest TRY/CATCH blocks along with corresponding ROLLBACK's you have to be careful. SQL Server really does not support nested transactions. So when you rollback, it rolls back all the operations from the outermost BEGIN TRAN.

SQL Server has a concept of savepoints which allows you to do partial rollbacks. I don't have much experience with it. May be someone else can give you more insight into it. http://msdn.microsoft.com/en-us/library/ms378414(v=sql.100).aspx
Go to Top of Page

Eagle_f90
Constraint Violating Yak Guru

424 Posts

Posted - 2012-04-12 : 14:28:56
quote:
Originally posted by sunitabeck

If you want to nest TRY/CATCH blocks along with corresponding ROLLBACK's you have to be careful. SQL Server really does not support nested transactions. So when you rollback, it rolls back all the operations from the outermost BEGIN TRAN.

SQL Server has a concept of savepoints which allows you to do partial rollbacks. I don't have much experience with it. May be someone else can give you more insight into it. http://msdn.microsoft.com/en-us/library/ms378414(v=sql.100).aspx


So if this script is going to be called from others I should remove both the try catch and the transaction statments?

--
If I get used to envying others...
Those things about my self I pride will slowly fade away.
-Stellvia
Go to Top of Page

Lamprey
Master Smack Fu Yak Hacker

4614 Posts

Posted - 2012-04-12 : 14:42:38
Not necessarily. You can raise an error from the CATACH block that will bubble up.

Also, there is no need for the transaction in the sample you showed because the action is atomic. But, if you are working on a more genral template, then that's cool.
Go to Top of Page

Eagle_f90
Constraint Violating Yak Guru

424 Posts

Posted - 2012-04-12 : 16:19:48
quote:
Originally posted by Lamprey

Not necessarily. You can raise an error from the CATACH block that will bubble up.

Also, there is no need for the transaction in the sample you showed because the action is atomic. But, if you are working on a more genral template, then that's cool.


How would I raise the error so the calling proc will know?
Just so I understand you right, since it is such a basic insert there is no need for the transaction calls? The insert will either succeed or fail.

--
If I get used to envying others...
Those things about my self I pride will slowly fade away.
-Stellvia
Go to Top of Page

Lamprey
Master Smack Fu Yak Hacker

4614 Posts

Posted - 2012-04-12 : 16:56:09
quote:
Originally posted by Eagle_f90
[br}How would I raise the error so the calling proc will know?

You use the RAISERROR statement:
http://msdn.microsoft.com/en-us/library/ms178592.aspx

Or if you are using 2012 you can use the THROW statement:
http://msdn.microsoft.com/en-us/library/ee677615.aspx

quote:

Just so I understand you right, since it is such a basic insert there is no need for the transaction calls? The insert will either succeed or fail.
That is correct, also known as the ACID property:
http://en.wikipedia.org/wiki/ACID
Go to Top of Page

Eagle_f90
Constraint Violating Yak Guru

424 Posts

Posted - 2012-04-13 : 11:15:23
Thanks for the help.

--
If I get used to envying others...
Those things about my self I pride will slowly fade away.
-Stellvia
Go to Top of Page
   

- Advertisement -