2011-11-03 71 views
2

如果由於違反外鍵約束而無法成功執行刪除語句,是否有辦法在SQL Server中中止存儲過程?默認情況下,該過程似乎忽略錯誤並繼續下一個語句。在外鍵約束違規中取消存儲過程

但是,對於其他類型的錯誤(例如,從不存在的表中刪除),過程將中止。

示例步驟:

SET ANSI_NULLS ON 
SET QUOTED_IDENTIFIER ON 
GO 
CREATE PROCEDURE [dbo].[TestSP] 
AS 
BEGIN 
    SET NOCOUNT ON; 

    print 'BEFORE'; 

    DELETE FROM ExistingWithConstraints; 
    print 'AFTER DELETE ExistingWithConstraints'; 

    DELETE FROM NonExisting; 
    print 'AFTER DELETE NonExisting'; 
END 

產生輸出(請注意,上述的最後一個消息不打印):

BEFORE 
<snip constraint violation error message> 
AFTER DELETE ExistingWithConstraints  
<snip invalid object name error message> 

回答

3

使用事務和恰當的錯誤處理

CREATE PROCEDURE [dbo].[TestSP] 
AS 
SET XACT_ABORT, NOCOUNT ON 
DECLARE @starttrancount int 

BEGIN TRY 
    SELECT @starttrancount = @@TRANCOUNT 

    IF @starttrancount = 0 
     BEGIN TRANSACTION 

    DELETE FROM ExistingWithConstraints; 
    DELETE FROM NonExisting; 

    IF @starttrancount = 0 
     COMMIT TRANSACTION 
END TRY 
BEGIN CATCH 
    IF XACT_STATE() <> 0 AND @starttrancount = 0 
     ROLLBACK TRANSACTION 
    RAISERROR [rethrow caught error using @ErrorNumber, @ErrorMessage, etc] 
END CATCH 
GO 

這是基於我的答案在這裏:Nested stored procedures containing TRY CATCH ROLLBACK pattern?

+0

如果'@@ TRANCOUNT> 0',您可以使用保存點來回滾由「TestSP」完成的err處理程序修改 - 這是我們在此使用的更通用的模式。 – wqw

+0

@wqw:我自己不使用保存點:數據庫調用應該是原子的。我跟着我的鏈接,你會看到Remus使用這些模板的另一個模板。您還必須小心使用XACT_ABORT,這會導致交易失敗 – gbn

-1

執行進行以允許你檢查@@ ERROR標準可變爲了問題。一個更現代的方式來做事,雖然它使用在try..catch塊加在2005年的SQL:

http://msdn.microsoft.com/en-us/library/ms179296.aspx

+0

-1所有提及@@錯誤 – gbn

+0

@gbn:爲什麼不呢? - 我仍然看到大量的編程方式(當然不是我)! –

+0

我們開始教育他們的時代,不是嗎。 – gbn