[英]Error Handling in SQL Server Stored Procedures
I have a fairly complex SP (logic wise) with nested IF BEGIN END ELSE
, there are multiple end points in this nested logic where the logic fails and I RAISERROR
and two places that result in success and SQL being actioned. 我有一个相当复杂的SP(逻辑明智),带有嵌套的IF BEGIN END ELSE
,在此嵌套逻辑中有多个端点,其中逻辑失败,并且我RAISERROR
和导致成功并执行SQL的两个地方。
How, at the end of the SP can I trap the errors and do a IF Error Count>0 THEN ROLLBACK
如何在SP的末尾捕获错误并执行IF Error Count>0 THEN ROLLBACK
DECLARE @errCount int=0
DECLARE @DataSetCount int=0
DECLARE @countCurrent int=0
DECLARE @countHistorical int=0
IF (isnumeric(@DataSetID)=(0) OR @DataSetID=(0))
BEGIN
RAISERROR('The DataSet specfied does not appear to be valid', 5, 1)
END
ELSE
IF (@Destination='C' OR @Destination='H')
BEGIN
if Exists (SELECT NULL from tblOpportunityDataSets where DataSetID=@DataSetID)
BEGIN
SET @countCurrent=(SELECT COUNT(1) from tblOptyRecordsCurrent where DataSetID=@DataSetID)
SET @countHistorical=(SELECT COUNT(1) from tblOptyRecordsHistorical where DataSetID=@DataSetID)
IF @destination='C'
BEGIN
if @countCurrent>0
BEGIN
RAISERROR('There are already existing records in the Current Tables for the specified DataSet', 5, 1)
END ELSE
if @countHistorical=0
BEGIN
RAISERROR('There do not appear to be any records in the Historical Tables to transfer for the specified Dataset', 5, 1)
END ELSE
BEGIN
-- ENTER TRANSFER CODE
INSERT INTO tblRecordsHistorical
( X, Y, Z )
SELECT X, Y, Z FROM tblA
WHERE x=y
-- Check that record count in both tables match
SET @countCurrent=(SELECT COUNT(1) from tblOptyRecordsCurrent where DataSetID=@DataSetID)
SET @countHistorical=(SELECT COUNT(1) from tblOptyRecordsHistorical where DataSetID=@DataSetID)
IF (@countCurrent<>@countHistorical)
BEGIN
RAISERROR('There was an error whilst copying the records into the Historical Tables, Source and Destination Record Count do not match', 5, 1)
END ELSE
BEGIN
END
END
END ELSE
IF @Destination='H'
BEGIN
if @countHistorical>0
BEGIN
RAISERROR('There are already existing records in the Historical Tables for the specified DataSet', 5, 1)
END ELSE
if @countCurrent=0
BEGIN
RAISERROR('There do not appear to be any records in the Historical Tables to transfer for the specified Dataset', 5, 1)
END ELSE
BEGIN
RAISERROR('DataSet Found, ready to transfer records to HISTORICAL', 5, 1)
-- ENTER TRANSFER CODE
INSERT INTO tblOptyRecordsCurrent
( X, Y, Z )
SELECT X, Y, Z FROM tblB
WHERE x=y
-- Check that record count in both tables match
SET @countCurrent=(SELECT COUNT(1) from tblOptyRecordsCurrent where DataSetID=@DataSetID)
SET @countHistorical=(SELECT COUNT(1) from tblOptyRecordsHistorical where DataSetID=@DataSetID)
END
END
END
ELSE
BEGIN
RAISERROR('The DataSet you have specified cannot be found', 5, 1)
END
END
ELSE
BEGIN
RAISERROR('You have not specified a valid Destination', 5, 1)
END
Note that in the two sections that contain the INSERT INTO code, there will be at least two additional SQL Action Statements, which must all work or they all fail. 请注意,在包含INSERT INTO代码的两部分中,将至少有两个附加的SQL操作语句,这些语句必须全部工作或全部失败。
EDIT: I've gone with 编辑:我去了
BEGIN TRAN
BEGIN TRY
-- STATEMENT 1
INSERT INTO X WHERE Y
-- STATEMENT 2
DELETE FROM X WHERE Y
-- STATEMENT 3
UPDATE X WHERE Y
COMMIT
END TRY
BEGIN CATCH
ROLLBACK TRAN
RAISERROR('There was an error whilst copying the records into the Current Tables. The Transaction has been rolled back', 5, 1)
END CATCH
In order to be able to do a rollback
, you need to do a begin transaction
at the start. 为了能够进行rollback
,您需要在begin transaction
。
Then you either commit
or rollback
the actions. 然后,您commit
或rollback
操作。
http://msdn.microsoft.com/en-us/library/ms174377 http://msdn.microsoft.com/en-us/library/ms174377
You may find the try/catch
syntax easier 您可能会发现try/catch
语法更容易
http://msdn.microsoft.com/en-us/library/ms175976(v=sql.90).aspx http://msdn.microsoft.com/en-us/library/ms175976(v=sql.90).aspx
You can use transaction inside stored procedure; 您可以在存储过程中使用事务; please refer the link Transaction in SP 请参考SP中的链接Transaction
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.