2013-04-22 88 views
3

我想知道是否有人能指引我朝着正確的方向發展。這是我在SQL中任何類型的錯誤處理方面的第一次嘗試,我擔心我錯過了某些東西或誤解了錯誤處理的概念。存儲過程中的多重錯誤處理

我有一個過程,基本上需要3個值,然後嘗試查看是否存在其中一個值。如果確實如此,則執行更新聲明。

從本質上講,我想做到以下幾點: - 返回「1」,如果沒有錯誤遇到 - 返回一個錯誤,如果更新語句失敗 - 如果SELECT語句未能找到記錄 返回一個錯誤更新任何記錄

以下是我的程序。目前,無論何時我運行它,它都會返回一個'1',表示沒有錯誤,這並不是我期望的,因爲我正在傳遞虛假值並試圖破壞它。有人可以幫助指出我做錯了什麼,或者甚至有可能嗎?

alter PROCEDURE [dbo].prc_update_SPRO_refill_status        
@result_code char(2),        
@result_string char(10),              
@rx_id char(20)   


AS        
BEGIN        


SET NOCOUNT ON; 
BEGIN TRANSACTION         
BEGIN TRY 

DECLARE @prescription_orders_id varchar(20) 
DECLARE @ErrorVar INT; 
DECLARE @RowCountVar INT; 

IF @result_code = 0 
BEGIN 
SELECT @prescription_orders_id = prescription_orders_id 
FROM prescription_orders 
WHERE rx_external_id = @rx_id 
     -- Return error if record not found 

UPDATE prescription_orders_fills 
SET fill_status_code = 'R' 
WHERE prescription_orders_id = @prescription_orders_id 
    AND fill_status_code = 'P' 
    AND fill_number > 1 
     -- return error if record not found 
     -- return error if more then 1 record update 


END            
END TRY 
BEGIN CATCH 
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; 
IF @@TRANCOUNT > 0 
    ROLLBACK TRANSACTION; 
END CATCH; 
IF @@TRANCOUNT > 0 
BEGIN 
COMMIT TRANSACTION 
SELECT 1 as ERROR_NUMBER 
END              
END 

回答

2

我覺得這裏的問題很簡單:你期待的TRY失敗,碰到你進入CATCH塊時也不例外也有提升。想想這個:下面的查詢是否因爲沒有更新行而引發錯誤?

CREATE TABLE #foo(a INT); 

UPDATE #foo SET a = 1 WHERE a = 2; 

這裏沒有錯誤信息,所以沒有理由觸發CATCH。如果您想測試您的錯誤處理,請在其中輸入實際的錯誤情況。例如:

BEGIN TRY 
    IF @force_error = 1 
    BEGIN 
    SELECT 1/0; 
    END 
END TRY 
BEGIN CATCH 
    -- now you should get here... 
END CATCH 

而且正如我在評論中提到 - 使用RETURN發送錯誤數/狀態代碼返回給調用者。沒有理由調用記錄集所需的所有腳手架來返回單個標量值。

0

我2美分

alter PROCEDURE [dbo].prc_update_SPRO_refill_status        
@result_code char(2),        
@result_string char(10),              
@rx_id char(20)   


AS        
BEGIN        


SET NOCOUNT ON; 

SET XACT_ABORT ON; // 1,這是很好的實現這個嘗試前

BEGIN TRY 
BEGIN TRANSACTION ; **// 2 start transaction after try** 

DECLARE @prescription_orders_id varchar(20) 
DECLARE @ErrorVar INT; 
DECLARE @RowCountVar INT; 

IF @result_code = 0 
    BEGIN 
     ... 
     ... 
     ... 
     ... 
    END       

END TRY 
BEGIN CATCH 
    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; 
    IF @@TRANCOUNT > 0 
     ROLLBACK TRANSACTION; 
END CATCH; 

    IF @@TRANCOUNT > 0 
    BEGIN 
     COMMIT TRANSACTION; 
     SELECT 1 as ERROR_NUMBER ; 
    END 

END