2011-06-13 48 views
4

我有一個包含一些T-SQL語句的SP(存儲過程).....sql server:插入到事務中的一個表中以記錄錯誤發生?

所有的T-sql語句都在一個事務塊中,並且通過發生任何錯誤,我會回滾每一件事。

這樣的:

BEGIN TRANSACTION 
..... 
..... 
IF @X=1 
BEGIN 
    declare cu cursor for select col1,col2 from Table1 where [email protected] 
    open cu 
    fetch next from cuinto @A, @B 
    while @@Fetch_Status = 0 
    BEGIN 
     ..... 
     ...... 
     IF @@ERROR <>0 
     BEGIN 
      ROLLBACK TRANSACTION 
      RETURN 
     END 
END 
..... 
..... 

的SP運行不正常,我找不到它的resean是什麼..... 我認爲這是登錄SP中的每一個操作是個好主意通過一些數據插入到表 我的問題是:

由於它採用的是交易,每次插入都將回滾.....

你對此有何看法?有沒有其他方法?

謝謝

+0

可能的重複[這是存儲過程中的良好寫入事務](http://stackoverflow.com/questions/6321554/is-this-good-writen-transaction-in-stored-procedure) – gbn 2011-06-13 09:03:51

回答

-2

您也可以Exception Handling使用Try Catch以及

Begin Try 
    BEGIN TRANSACTION 
..... 
..... 
IF @X=1 
BEGIN 
    declare cu cursor for select col1,col2 from Table1 where [email protected] 
    open cu 
    fetch next from cuinto @A, @B 
    while @@Fetch_Status = 0 
    BEGIN 
     ..... 
     ...... 
     //Your insert statement.... 
END 
..... 
..... 
Commit Tran 

End Try 

Begin Catch 
     Rollback Tran 
     DECLARE @ErrorMessage NVARCHAR(4000); 
     DECLARE @ErrorSeverity INT; 
     DECLARE @ErrorState INT; 

     SELECT @ErrorMessage = ERROR_MESSAGE(), 
     @ErrorSeverity = ERROR_SEVERITY(), 
     @ErrorState = ERROR_STATE(); 

     -- Use RAISERROR inside the CATCH block to return 
     -- error information about the original error that 
     -- caused execution to jump to the CATCH block. 
     RAISERROR (@ErrorMessage, -- Message text. 
      @ErrorSeverity, -- Severity. 
      @ErrorState -- State. 
      ); 

End Catch 
+0

@@ ERROR isn足夠可靠:始終使用TRY/CATCH – gbn 2011-06-13 09:03:25

+0

是的。瞭解。謝謝你。 – Pankaj 2011-06-13 09:07:30

1

我改寫了你的代碼使用TransactionTry Catch

CREATE PROCEDURE [dbo].[mySP] 
(
    @X int, @Y int, 
    @Return_Message VARCHAR(1024) = '' OUT 
) 
AS 

    SET NOCOUNT ON; 

    Declare @A varchar(100) @B varchar(100) 

BEGIN TRY 

    BEGIN TRAN 

     IF @X=1 
     BEGIN 
      declare cu cursor for select col1,col2 from Table1 where [email protected] 
      open cu 
      fetch next from cu into @A, @B 
      while @@Fetch_Status = 0 
      BEGIN 
       -- ..... 
       -- do your stuff 
       FETCH NEXT FROM cu into @A, @B    
      END 
     END 

    COMMIT TRAN 

    SELECT @Return_Message = 'All OK' 

    /************************************* 
    * Return from the Stored Procedure 
    *************************************/ 
    RETURN 1 -- success 

END TRY 

BEGIN CATCH 
    /************************************* 
    * if errors rollback 
    *************************************/ 
    IF @@TRANCOUNT > 0 ROLLBACK 

    SELECT @Return_Message = @ErrorStep + ' ' 
     + cast(ERROR_NUMBER() as varchar(20)) + ' line: ' 
     + cast(ERROR_LINE() as varchar(20)) + ' ' 
     + ERROR_MESSAGE() + ' > ' 
     + ERROR_PROCEDURE() 

    /************************************* 
    * Return from the Stored Procedure 
    *************************************/ 
    RETURN 0 -- fail 

END CATCH 

給你一個真實的例子實施SP用法:

declare @ret int, @Return_Message VARCHAR(1024) 

EXEC @ret = mySP 1, 2, @Return_Message OUTPUT 

-- the SP Fail so print or store the return message with errors ... 
if @ret = 0 print @Return_Message 
3

沒有現在之所以使用@@ ERROR:try/catch語句是更爲可靠。要了解更多,我推薦閱讀Erland Sommarskog的"Error Handling in SQL 2005 and Later"這是關於這個問題的權威性文章

在這種情況下,沒有TRY/CATCH,一些錯誤是批量中止:這意味着代碼停止並且沒有錯誤被困住。除了編譯錯誤之外,這是用TRY/CATCH修復的。

這個模板是從我以前的答案Nested stored procedures containing TRY CATCH ROLLBACK pattern?

CREATE PROCEDURE [Name] 
AS 
SET XACT_ABORT, NOCOUNT ON 

DECLARE @starttrancount int 

BEGIN TRY 
    SELECT @starttrancount = @@TRANCOUNT 

    IF @starttrancount = 0 
     BEGIN TRANSACTION 

     [...Perform work, call nested procedures...] 

    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] 
    -- if desired INSERT ExceptionLogTable() .. 
END CATCH 
GO 

如果使用SET XACT_ABORT ON(我估計應該是最佳實踐)拍攝,然後在任何CATCH塊@@ TRANCOUNT是零。所以如果你願意,你可以在這裏寫入一個日誌記錄表,除了拋出一個錯誤。

+0

對於SET XACT_ABORT的+1已被研究。要學習新的。謝謝:) – Pankaj 2011-06-13 09:12:33

+0

@SQL:..結合TRY/CATCH使您的代碼更可靠,我們一直使用它。 http://stackoverflow.com/search?q=user%3A27535+XACT_ABORT – gbn 2011-06-13 09:14:51

+0

是的。瞭解。我的練習也是這樣。但是我的@@錯誤,這不應該真的存在。 – Pankaj 2011-06-13 09:23:07

相關問題