0

SQLエージェントジョブを設定し、そのジョブにストアドプロシージャを実行するステップがあります。そのストアドプロシージャが失敗した場合、SQLエージェントジョブはエラーメッセージを表示しますが、他の情報はありません。スタックトレースまたは少なくとも実行中のストアドプロシージャと行番号のようなものは非常に便利です。

たとえば、次のストアドプロシージャが実行されると、「ユーザーとして実行:NT AUTHORITY \NETWORKSERVICE。Start[SQLSTATE01000](メッセージ0)無効なオブジェクト名'NonExistentTable'。[SQLSTATE42S02](エラー208)」などのエラーメッセージが表示されます。ステップが失敗しました。」正確にどこで障害が発生したかは示されません。

CREATE PROCEDURE TestSpLogging AS 
BEGIN
PRINT 'Start'
SELECT * FROM NonExistentTable
PRINT 'End'
END

この情報を公開するための最良の方法は何ですか?

4

2 に答える 2

2

http://www.sommarskog.se/error_handling_2005.htmlで詳述されているアプローチを使用すると、これまでのところ十分に機能しているようです。最上位のストアドプロシージャを更新するだけで、失敗したストアドプロシージャの名前と行番号がSQLエージェントに出力されます。

出力エラーは次のようになります。

ユーザーとして実行:NT AUTHORITY\NETWORKSERVICE。*** [InnerInnerStoredProc2]、5。Errno 208:無効なオブジェクト名'NonExistentTable'。[SQLSTATE 42000](エラー50000)[SQLSTATE 01000](エラー0)を開始します。ステップは失敗しました。

手順の概要:

次のエラーハンドラストアドプロシージャを作成します。

CREATE PROCEDURE error_handler_sp AS

DECLARE @errmsg   nvarchar(2048),
        @severity tinyint,
        @state    tinyint,
        @errno    int,
        @proc     sysname,
        @lineno   int

SELECT @errmsg = error_message(), @severity = error_severity(),   -- 10
       @state  = error_state(), @errno = error_number(),
       @proc   = error_procedure(), @lineno = error_line()

IF @errmsg NOT LIKE '***%'                                        -- 11  
BEGIN 
   SELECT @errmsg = '*** ' + coalesce(quotename(@proc), '<dynamic SQL>') + 
                    ', ' + ltrim(str(@lineno)) + '. Errno ' + 
                    ltrim(str(@errno)) + ': ' + @errmsg
   RAISERROR(@errmsg, @severity, @state)
END
ELSE
   RAISERROR(@errmsg, @severity, @state)
go

次のように、最上位のストアドプロシージャをtrycatchでラップします

BEGIN TRY
   SET NOCOUNT ON
   SET XACT_ABORT ON

EXEC InnerStoredProc1
EXEC InnerStoredProc2

END TRY
BEGIN CATCH
   IF @@trancount > 0 ROLLBACK TRANSACTION
   EXEC error_handler_sp
   RETURN 55555
END CATCH
于 2011-03-11T00:39:11.697 に答える
1

これを行う1つの方法は、ストアドプロシージャにエラー処理を追加することです。ここで使用する簡単な方法は次のようなものです

declare
    @Error                 int
   ,@ErrorMsg              varchar(1000)
   ,@StepName              varchar(500)
   ,@ProcedureName         sysname
   ,@dtDateTime            datetime

select @ProcedureName = object_name(@@procid)

begin try
select @StepName = 'Step 01: Select from table
PRINT 'Start'
SELECT * FROM NonExistentTable
PRINT 'End'

end try

begin catch
   select @Error = @@ERROR
   set @ErrorMsg = @ProcedureName + ' Error: ' + @StepName
                                  + ', dbErrorNbr:' + IsNull(convert(varchar(10),@Error),'Null')
   raiserror (@ErrorMsg, 16, 1) with nowait
end catch
于 2011-03-10T23:40:53.787 に答える