Web アプリケーション内で実行されるアクション、SQL サーバー エージェント ジョブ、データベースに対して手動でクエリを実行するアクションの監査証跡を作成しようとしています。トリガーを使用して、特定のテーブルの更新、挿入、および削除をキャッチしようとしています。
全体として、このプロセスは機能しています。たとえば、ユーザーが Web アプリケーションで更新を実行し、トリガーが更新されたデータを、アクションを実行した人のユーザー名を含む、定義した監査証跡テーブルに書き込みます。これは、Web アプリケーションまたは手動クエリの観点からは正常に機能しますが、特定のクエリを実行した SQL Server エージェント ジョブも多数あります。各エージェント ジョブは、同じユーザー名で実行されます。これも正常に機能し、ユーザー名をテーブルに正しく入力しますが、このクエリを呼び出すジョブが見つかりません。
私の現在の「解決策」は、トリガー時に現在実行されているジョブを見つけることでした。そのうちの1つが正しいものでなければならないからです。使用:
CREATE TABLE #xp_results
(
job_id UNIQUEIDENTIFIER NOT NULL,
last_run_date INT NOT NULL,
last_run_time INT NOT NULL,
next_run_date INT NOT NULL,
next_run_time INT NOT NULL,
next_run_schedule_id INT NOT NULL,
requested_to_run INT NOT NULL, -- BOOL
request_source INT NOT NULL,
request_source_id sysname COLLATE database_default NULL,
running INT NOT NULL, -- BOOL
current_step INT NOT NULL,
current_retry_attempt INT NOT NULL,
job_state INT NOT NULL
)
INSERT INTO #xp_results
EXECUTE master.dbo.xp_sqlagent_enum_jobs 1, 'sa'
SELECT @runningJobs = STUFF((SELECT ',' + j.name
FROM #xp_results r
INNER JOIN msdb..sysjobs j ON r.job_id = j.job_id
WHERE running = 1
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
DROP TABLE #xp_results
テストのために特定のジョブを実行しましたが、動作しているように見えます。実行中のその他のジョブは にリストされますが@runningJobs
、それを実行するジョブは記録されません。トリガーが実行されるまでに、ジョブは終了していると思います。
トリガーを開始するクエリを呼び出すジョブを見つける方法はありますか?
編集:SELECT
上記のクエリを変更して、過去 2 分以内に実行された、または現在実行中のジョブを取得しようとしました。SQL クエリは次のようになります。
SELECT @runningJobs = STUFF((SELECT ',' + j.name
FROM #xp_results r
INNER JOIN msdb..sysjobs j ON r.job_id = j.job_id
WHERE (last_run_date = CAST(REPLACE(LEFT(CONVERT(VARCHAR, getdate(), 120), 10), '-', '') AS INT)
AND last_run_time > CAST(REPLACE(LEFT(CONVERT(VARCHAR,getdate(),108), 8), ':', '') AS INT) - 200)
OR running = 1
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
ジョブを実行し、ジョブの実行中に上記のクエリを実行すると、正しいジョブが返されます。ただし、SQL Server エージェント ジョブを介して、または SSIS で手動で実行して SSIS パッケージを実行すると、@runningJobs
は読み込まれず、単に が返されますNULL
。
だから私は今、それがSSISとのパーミッションの問題だと考えていmaster.dbo.xp_sqlagent_enum_jobs
ます. 他のアイデアはありますか?
編集#2:実際には、それがパーミッションエラーだとは思わないでください。このコードの下にステートメントがありINSERT
ます。パーミッション エラーの場合、INSERT
ステートメントは実行されないため、監査行はデータベースに追加されません。runningJobs
そのため、フィールドが入力されていないだけで、データベースに行が追加されているためです。奇妙な時代。
編集#3:明確にしたいのですが、各仕事に行って何かを変更する必要のない解決策を探しています。これを実行可能な解決策にするには、仕事が多すぎます。