範例:使用伺服器事件的 WMI 提供者建立 SQL Server Agent 警示

使用 WMI 事件提供者的常見方式為建立回應特定事件的 SQL Server Agent 警示。 下列範例顯示一個簡單的警示,可將 XML 死結圖形事件儲存在資料表中,以便稍後進行分析。 SQL Server Agent 會提交 WQL 要求、接收 WMI 事件,以及執行工作來回應事件。 請注意,雖然在處理通知訊息時包含數個 Service Broker 物件,但是 WMI 事件提供者會處理建立與管理這些物件的詳細資料。

範例

首先,在 AdventureWorks 資料庫中建立一個資料表來容納死結圖形事件。 此資料表包含兩個資料行:AlertTime 資料行容納警示執行的時間,而 DeadlockGraph 資料行容納其中包含死結圖形的 XML 文件。

接著,建立警示。 指令碼會先建立警示將執行的工作、將作業步驟加入到工作中,然後將工作目標瞄準為目前的 SQL Server 執行個體。 然後,指令碼會建立警示。

作業步驟會擷取 WMI 事件執行個體的 TextData 屬性,然後將該值插入 DeadlockEvents 資料表的 DeadlockGraph 資料行中。 請注意,SQL Server 會以隱含的方式,將字串轉換為 XML 格式。 作業步驟會使用 Transact-SQL 子系統,因此,作業步驟不會指定 Proxy。

每當記錄死結圖形追蹤事件時,警示就會執行作業。 對於 WMI 警示,SQL Server Agent 會使用指定的命名空間和 WQL 陳述式來建立通知查詢。 SQL Server Agent 會針對此警示監視本機電腦上的預設執行個體。 WQL 陳述式會要求預設執行個體中的任何 DEADLOCK_GRAPH 事件。 若要變更警示所監視的執行個體,將警示的執行個體名稱取代為 @wmi\_namespace 中的 MSSQLSERVER。

[!附註]

若要讓 SQL Server Agent 接收 WMI 事件,必須在 msdb 和 AdventureWorks2012 中啟用 Service Broker。

USE AdventureWorks ;
GO

IF OBJECT_ID('DeadlockEvents', 'U') IS NOT NULL
BEGIN
    DROP TABLE DeadlockEvents ;
END ;
GO

CREATE TABLE DeadlockEvents
    (AlertTime DATETIME, DeadlockGraph XML) ;
GO
-- Add a job for the alert to run.

EXEC  msdb.dbo.sp_add_job @job_name=N'Capture Deadlock Graph', 
    @enabled=1, 
    @description=N'Job for responding to DEADLOCK_GRAPH events' ;
GO

-- Add a jobstep that inserts the current time and the deadlock graph into
-- the DeadlockEvents table.

EXEC msdb.dbo.sp_add_jobstep
    @job_name = N'Capture Deadlock Graph',
    @step_name=N'Insert graph into LogEvents',
    @step_id=1, 
    @on_success_action=1, 
    @on_fail_action=2, 
    @subsystem=N'TSQL', 
    @command= N'INSERT INTO DeadlockEvents
                (AlertTime, DeadlockGraph)
                VALUES (getdate(), N''$(ESCAPE_SQUOTE(WMI(TextData)))'')',
    @database_name=N'AdventureWorks' ;
GO

-- Set the job server for the job to the current instance of SQL Server.

EXEC msdb.dbo.sp_add_jobserver @job_name = N'Capture Deadlock Graph' ;
GO

-- Add an alert that responds to all DEADLOCK_GRAPH events for
-- the default instance. To monitor deadlocks for a different instance,
-- change MSSQLSERVER to the name of the instance.

EXEC msdb.dbo.sp_add_alert @name=N'Respond to DEADLOCK_GRAPH', 
@wmi_namespace=N'\\.\root\Microsoft\SqlServer\ServerEvents\MSSQLSERVER', 
    @wmi_query=N'SELECT * FROM DEADLOCK_GRAPH', 
    @job_name='Capture Deadlock Graph' ;
GO

測試範例

若要查看作業執行,請先誘發死結。 在 SQL Server Management Studio 中,開啟兩個 [SQL 查詢] 索引標籤,並將兩個查詢連接到相同的執行個體。 在其中一個查詢索引標籤中執行下列指令碼。 這個指令碼會產生一個結果集並完成。

USE AdventureWorks ;
GO

BEGIN TRANSACTION ;
GO

SELECT TOP(1) Name FROM Production.Product WITH (XLOCK) ;
GO

在另一個查詢索引標籤中執行下列指令碼。 此指令碼會產生一個結果集,然後封鎖,等待取得 Production.Product 上的鎖定。

USE AdventureWorks ;
GO

BEGIN TRANSACTION ;
GO

SELECT TOP(1) Name FROM Production.Location WITH (XLOCK) ;
GO

SELECT TOP(1) Name FROM Production.Product WITH (XLOCK) ;
GO

在第一個查詢索引標籤中執行下列指令碼。 此指令碼會封鎖,等待取得 Production.Location 上的鎖定。 短暫的逾時之後,SQL Server 將會選擇此指令碼或範例中的指令碼,做為死結的犧牲者,然後結束交易。

SELECT TOP(1) Name FROM Production.Location WITH (XLOCK) ;
GO

誘發死結之後稍等一陣子,讓 SQL Server Agent 啟動警示並執行作業。 執行下列指令碼來檢查 DeadlockEvents 資料表的內容:

SELECT * FROM DeadlockEvents ;
GO

DeadlockGraph 資料行應該包含顯示死結圖形事件所有屬性的 XML 文件。

請參閱

概念

伺服器事件的 WMI 提供者概念