0

私は、いくつかのレイヤーに深く入るストアドプロシージャによって開始されるプロセスを持っています。最大12のストアドプロシージャが関与する可能性があります。ストアドプロシージャIDを使用したテーブル監査トリガー

上記の処理中に列が正しく更新されていないテーブルがあります。誤った更新を行っているストアドプロシージャはどれですか。

私はトリガーを介してテーブルの監査を見てきましたが、SCOPE_IDENTITY関数を使用して、どのストアドプロシージャが原因であるかを特定しようとしましたが、監査テーブルにNULL値を返します。

私は何をしようとしていますか?私は基本的にはこれまでに限られた成功しか得ていなかったデバッグの代わりにこれを使用しようとしています。情報をキャプチャするためにストアドプロシージャを編集したくないのです。

私のコードは次のとおりです。問題のテーブルを更新するためのテストストアドプロシージャを作成しました。

--Create test Sproc 

    IF EXISTS (SELECT * FROM sys.objects (NOLOCK) WHERE name LIKE 'usp_update_pkd') 
    BEGIN 
     DROP PROCEDURE usp_update_pkd 
    END 
    GO 

    CREATE PROCEDURE usp_update_pkd 
    @p_order_number VARCHAR(30) 

    AS 

    UPDATE t_pick_detail 
    SET status = 'XXX' 
    WHERE order_number = @p_order_number 
    RETURN 
    GO 


    --Create Audit Table 
    IF EXISTS (SELECT * FROM sys.objects (NOLOCK) WHERE name LIKE 't_pkd_audit') 
     BEGIN 
     DROP TABLE t_pkd_audit 
     END 
    GO 
    CREATE TABLE t_pkd_audit 
    (
     order_audit_id INTEGER IDENTITY(1,1) PRIMARY KEY, 
     wave_id  VARCHAR(10), 
     work_type  VARCHAR(20), 
     order_number VARCHAR(20), 
     sproc_id  NVARCHAR(128), 
     updated_on  DATETIME 
    ) 
    GO 

     --Create Trigger 
     IF EXISTS (SELECT * FROM sys.objects (NOLOCK) WHERE name LIKE 'pkd_audit_record') 
    BEGIN 
     DROP TRIGGER pkd_audit_record 
    END 
    GO 

    CREATE TRIGGER pkd_audit_record ON t_pick_detail 
    AFTER UPDATE 
    AS 
    BEGIN 
     INSERT INTO t_pkd_audit 
     (wave_id, work_type, order_number, sproc_id, updated_on) 
     SELECT DISTINCT i.wave_id, i.work_type, i.order_number, CAST(SCOPE_IDENTITY() AS VARCHAR), GETDATE() 
     FROM t_pick_detail t 
     INNER JOIN inserted i 
     ON t.order_number = i.order_number 
     AND t.line_number = i.line_number 
    END 
    GO 

    --Execute test SProc 
    EXEC usp_update_pkd '4045' 

    --Check Results 
    SELECT * FROM t_pkd_audit (NOLOCK) 

--Result Set 
order_audit_id|wave_id|work_type|order_number|sproc_id|updated_on 
1    |NULL |17  |4045  |NULL |2017-06-22 00:47:52.513 

ご協力いただきまして誠にありがとうございます。

+0

あなたはcontext_infoを試しましたか? https://docs.microsoft.com/en-us/sql/t-sql/functions/context-info-transact-sql – Peter

+0

こんにちはPeterさん、私が読んだところでは、問題のストアドプロシージャを変更する必要があります。ソースコード内にcontext_infoの値を設定します。私の理解は正しいのですか? DMLの実行時にSQL Serverが暗黙的にどのプロシージャを追跡しているかが他にない場合は、それが機能する可能性があります。 – dska84

答えて

0

ストアドプロシージャ名を含む列を監査テーブルに追加します。デフォルト値があるので、トリガを変更する必要はありませんが、必要に応じてsproc_idを削除できます。デフォルト値は、context_infoに格納された@@ PROCIDを受け取り、それを使用してストアドプロシージャ名を取得します。あなたの12のストアドプロシージャのそれぞれについて

CREATE TABLE t_pkd_audit 
(
    order_audit_id INTEGER IDENTITY(1,1) PRIMARY KEY, 
    wave_id  VARCHAR(10), 
    work_type  VARCHAR(20), 
    order_number VARCHAR(20), 
    sproc_id  NVARCHAR(128), 
    updated_on  DATETIME, 
    SpName [varchar](128) NULL CONSTRAINT [DF_a_hist_sourceName] DEFAULT (object_name(CONVERT([int],CONVERT([varbinary](4),context_info())))) 
) 

、で始まる:それはCONTEXT_INFOでストアドプロシージャのIDを入れて、変数に親ストアドプロシージャのIDを格納する

declare @calledBy varbinary(128) = coalesce(Context_info(),0),@proc int 
select @proc = @@PROCID 
set context_info @proc 

各ストアドプロシージャの最後に。戻り値を使用する場合は、それぞれの戻り値の前にも、folowingコードを追加して、親ストアドプロシージャのidをcontext_infoに書き戻します。

set context_info @calledby 
+0

Peterに感謝します。最初のコメントを読んだ後、私は離れていくつか試してみました。あなたの助けをもう一度ありがとう。私はアプリケーションからのプロセスをトリガし、低いと、それが完了したときに、監査テーブルに違反しているsproc名が見えました!バグを見つけて修正しました! – dska84

関連する問題