3

誰かが私を正しい方向に向けることができるかどうか疑問に思っていました. これは、SQL であらゆる種類のエラー処理を試みる最初の試みであり、何かが完全に欠落しているか、エラー処理の概念を誤解しているのではないかと心配しています。

基本的に3つの値を取り、値の1つが存在するかどうかを確認しようとする手順があります。存在する場合は、更新ステートメントを実行します。

基本的に、私は次のことをしたいと思います: - エラーが発生しなかった場合は '1' を返します - Select ステートメントがレコードを見つけられなかった場合はエラーを返します - Update ステートメントがレコードを更新できなかった場合はエラーを返します

以下は私の手順です。現在、実行するたびに「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 
4

2 に答える 2

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エラー番号/ステータスコードを発信者に送り返すために使用します。レコードセットが単一のスカラー値を返すために必要なすべてのスキャフォールディングを呼び出す理由はありません。

于 2013-04-22T21:14:59.710 に答える
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;

XACT_ABORT をオンに設定します。// 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 
于 2013-04-22T21:26:59.853 に答える