はい、いくつかの複雑さと制限がありますが、これを行うことができます。これは推奨事項ではなく、単なる回答です。
SQLServer には、catch ブロックで使用するための ERROR_MESSAGE()、ERROR_NUMBER() などの組み込み関数が用意されています。
挿入/削除コードが自動コミット モード (begin tran なし、暗黙的なトランザクションなし) で実行される場合、挿入と削除は既にロールバックまたはコミットされているため、catch ブロックにエラー メッセージと番号を記録するだけで機能します。
そう
begin try
-- do work
end try
begin catch
insert into audit_table select ERROR_MESSAGE(), ERROR_NUMBER()
end catch
働ける。
TSQL コードまたはクライアントが begin tran または暗黙的なトランザクションを使用する場合、catch ブロック内のロジックはこれを考慮する必要があります。そうしないと、元のトランザクションがロールバックされたときにエラーの記録がロールバックされ、エラーの記録が残りません。
こんなのあったら…
begin try
begin tran
-- do work
if xact_state() = 1 commit tran
if xact_state() = -1 rollback tran
end try
begin catch
-- Now there is a good chance a transaction is still pending or uncomittable.
if xact_state() != 0 rollback tran -- assuming you always rollback.
-- Insert will be recorded because previous transaction was cleared.
insert into audit_table select ERROR_MESSAGE(), ERROR_NUMBER()
end catch
catch ブロックでコミットまたはロールバックせず、トランザクションがコミットできない場合、挿入は最終的にロールバックされ、エラーの記録はありません。
クライアントがトランザクションを管理している場合、クライアントがロールバックを発行するエラー ハンドラに問題がない限り、エラー情報を記録できない場合があります。また、ロールバックを発行すると、実際の根本原因を覆い隠すエラーが生成される場合があります。複雑さについてくよくよすることなく、クライアントがトランザクションを管理している場合、クライアントにエラーをキャッチして記録させる方がはるかに簡単です。