1. ホーム
  2. sql

[解決済み] SQL Serverで同じ例外を再スローする方法

2023-02-04 08:35:46

質問

SQL Server で発生したのと同じ例外を try ブロックで再スローしたいです。同じメッセージを投げることができますが、同じエラーを投げたいのです。

BEGIN TRANSACTION
    BEGIN TRY
        INSERT INTO Tags.tblDomain (DomainName, SubDomainId, DomainCode, Description)
            VALUES(@DomainName, @SubDomainId, @DomainCode, @Description)
        COMMIT TRANSACTION
    END TRY
    
    BEGIN CATCH
        declare @severity int; 
        declare @state int;

        select @severity=error_severity(), @state=error_state();

        RAISERROR(@@Error,@ErrorSeverity,@state);
        ROLLBACK TRANSACTION
    END CATCH

RAISERROR(@@Error, @ErrorSeverity, @state);

この行はエラーを表示しますが、私はこのような機能が欲しいのです。 これはエラー番号50000でエラーを発生させますが、私が渡しているエラー番号を投げさせたいのです。 @@error ,

このエラーNoをフロントエンドに取り込みたいのです。

すなわち

catch (SqlException ex)
{
    if ex.number==2627
    MessageBox.show("Duplicate value cannot be inserted");
}

このような機能が欲しい。 raiseerror . 私は、バックエンドでカスタムエラーメッセージを与えたくありません。

RAISEERROR で投げられるErrorNoを渡すと、以下のようなエラーが返されるはずです。

Msg 2627, Level 14, State 1, Procedure spOTest_DomainInsert,

14行目 UNIQUE KEY 制約 'UK_DomainCode' に違反しています。挿入できません。 オブジェクトに重複したキーを挿入できません。 'Tags.tblDomain' に重複キーを挿入できません。 文は終了されました。

EDITです。

ストアドプロシージャが複数のクエリを実行する必要があり、フロントエンドで例外を処理したい場合、try catchブロックを使用しない欠点は何でしょうか?

どのように解決するのですか?

ここでは、エラーが発生した場合に一連のステートメントをロールバックし、エラーメッセージを報告する、完全に機能するクリーンなコードサンプルを紹介します。

begin try
    begin transaction;

    ...

    commit transaction;
end try
begin catch
    if @@trancount > 0 rollback transaction;
    throw;
end catch

SQL 2012以前

begin try
    begin transaction;
    
    ...
    
    commit transaction;
end try
begin catch
    declare @ErrorMessage nvarchar(max), @ErrorSeverity int, @ErrorState int;
    select @ErrorMessage = ERROR_MESSAGE() + ' Line ' + cast(ERROR_LINE() as nvarchar(5)), @ErrorSeverity = ERROR_SEVERITY(), @ErrorState = ERROR_STATE();
    if @@trancount > 0 rollback transaction;
    raiserror (@ErrorMessage, @ErrorSeverity, @ErrorState);
end catch