2013-04-22 86 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