Reputation: 12711
I'm running the following stored procedure and I'm receiving the error
The COMMIT TRANSACTION request has no corresponding BEGIN TRANSACTION.
what am I missing here?
CREATE PROCEDURE spImportData
AS
BEGIN TRANSACTION
BEGIN TRY
SET IDENTITY_INSERT PINCDOCControlNew..tblActionType ON
END TRY
BEGIN CATCH
PRINT 'IDENTITY_INSERT IS ON'
END CATCH
GO
BEGIN TRY
INSERT INTO PINCDOCControlNew..tblActionType(ActionTypeID,ActionType,ActionTypeDescription)
SELECT ActionTypeID,ActionType,ActionTypeDescription
FROM PINCDOCControlOld..tblActionType
SET IDENTITY_INSERT PINCDOCControlNew..tblActionType OFF
END TRY
BEGIN CATCH
SET IDENTITY_INSERT PINCDOCControlNew..tblActionType OFF
EXECUTE usp_GetErrorInfo
END CATCH
BEGIN TRY
SET IDENTITY_INSERT PINCDOCControlNew..tblArea ON
END TRY
BEGIN CATCH
PRINT 'IDENTITY_INSERT IS ON'
END CATCH
GO
BEGIN TRY
INSERT INTO PINCDOCControlNew..tblArea(AreaID,AreaDescription,AreaNo)
SELECT AreaNo,AreaDescription,Area
FROM PINCDOCControlOld..tblArea
SET IDENTITY_INSERT PINCDOCControlNew..tblArea OFF
END TRY
BEGIN CATCH
SET IDENTITY_INSERT PINCDOCControlNew..tblArea OFF
EXECUTE usp_GetErrorInfo
END CATCH
IF @@ERROR <> 0
BEGIN
-- Rollback the transaction
ROLLBACK
-- Raise an error and return
RAISERROR ('Error in inserting.', 16, 1)
RETURN
END
COMMIT
Upvotes: 3
Views: 6441
Reputation: 754220
I would try to have just a single BEGIN TRY .... END TRY
block, in which you have all your logic that you want to execute. If anything goes wrong - anywhere in your logic - you'll be thrown into the BEGIN CATCH.... END CATCH
block.
Start your transaction before your BEGIN TRY
, and have the only COMMIT
as the last statement in your TRY
block - and in your CATCH
block, have a rollback.
Something like this:
CREATE PROCEDURE dbo.spImportData
AS
BEGIN TRANSACTION
BEGIN TRY
SET IDENTITY_INSERT PINCDOCControlNew..tblActionType ON
INSERT INTO
PINCDOCControlNew..tblActionType(ActionTypeID, ActionType, ActionTypeDescription)
SELECT
ActionTypeID, ActionType, ActionTypeDescription
FROM
PINCDOCControlOld..tblActionType
SET IDENTITY_INSERT PINCDOCControlNew..tblActionType OFF
-- tblArea
SET IDENTITY_INSERT PINCDOCControlNew..tblArea ON
INSERT INTO
PINCDOCControlNew..tblArea(AreaID, AreaDescription, AreaNo)
SELECT
AreaNo, AreaDescription, Area
FROM
PINCDOCControlOld..tblArea
SET IDENTITY_INSERT PINCDOCControlNew..tblArea OFF
COMMIT TRANSACTION
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
SET IDENTITY_INSERT PINCDOCControlNew..tblActionType OFF
SET IDENTITY_INSERT PINCDOCControlNew..tblArea OFF
EXECUTE usp_GetErrorInfo
RAISERROR ('Error in inserting.', 16, 1)
END CATCH
With this approach, you have exactly ONE BEGIN TRANSACTION
, and either one single corresponding COMMIT TRANSACTION
, or a single corresponding ROLLBACK TRANSACTION
I typically also add this SELECT
statement to my CATCH
block to get the error message and error code of what went wrong:
SELECT
ERROR_NUMBER() AS ErrorNumber,
ERROR_SEVERITY() AS ErrorSeverity,
ERROR_STATE() AS ErrorState,
ERROR_PROCEDURE() AS ErrorProcedure,
ERROR_LINE() AS ErrorLine,
ERROR_MESSAGE() AS ErrorMessage
Upvotes: 9
Reputation: 452947
what am i missing here?
You probably have a surplus rather than a deficit. You need to remove the GO
statements.
The only sensible interpretation of your script is that it is all intended to be part of the spImportData
stored procedure definition.
This ends at the first GO
statement (used by client tools to delimit batches) and the remaining batches are executed immediately in auto commit transactions as no explicit BEGIN TRAN
has been run. When the COMMIT
statement is reached there is nothing to commit hence the error.
Upvotes: 7