将 WQL 与 WMI Provider for Server Events 结合使用
管理应用程序通过发出 WMI 查询语言(WQL)语句,使用 WMI 提供程序访问服务器事件的 SQL Server 事件。 WQL 是结构化查询语言 (SQL) 的简化子集,它还包含一些特定于 WMI 的扩展。 在使用 WQL 时,应用程序针对 SQL Server 的特定实例、数据库或数据库对象(当前唯一支持的对象是队列)检索事件类型。 用于服务器事件的 WMI 提供程序将查询转换为在目标数据库中为数据库范围或对象范围事件通知创建的事件通知,或者在 服务器 范围事件通知的主数据库中创建。
例如,请考虑下列 WQL 查询:
SELECT * FROM DDL_DATABASE_LEVEL_EVENTS WHERE DatabaseName = 'AdventureWorks'
在以下查询中,WMI 提供程序试图在目标服务器上生成此事件通知的等效项:
USE AdventureWorks ;
GO
CREATE EVENT NOTIFICATION SQLWEP_76CF38C1_18BB_42DD_A7DC_C8820155B0E9
ON DATABASE
WITH FAN_IN
FOR DDL_DATABASE_LEVEL_EVENTS
TO SERVICE
'SQL/Notifications/ProcessWMIEventProviderNotification/v1.0',
'A7E5521A-1CA6-4741-865D-826F804E5135';
GO
WQL 查询 (FROM
) 的 DDL_DATABASE_LEVEL_EVENTS
子句中的参数可以为可对其创建事件通知的任何有效事件。 SELECT
和 WHERE
子句中的参数可以指定与某一事件或其父事件关联的任何事件属性。 有关有效事件和事件属性的列表,请参阅事件通知(数据库引擎)。
WMI Provider for Server Events 显式支持以下 WQL 语法。 也可以指定附加 WQL 语法,但该语法并非特定于此提供程序,并且由 WMI 主机服务进行分析。 有关 WMI 查询语言的详细信息,请参阅 Microsoft Developer Network (MSDN) 上的 WQL 文档。
语法
SELECT { event_property [ ,...n ] | * }
FROM event_type
WHERE where_condition
参数
event_property
事件的属性。 示例包括 PostTime
、SPID
和 LoginName
。 查找 WMI 提供程序中 为服务器事件类和属性 列出的每个事件,以确定它保存的属性。 例如,DDL_DATABASE_LEVEL_EVENTS 事件具有 DatabaseName
和 UserName
属性。 事件还从其父事件继承 SQLInstance
、LoginName
、PostTime
、SPID
和 ComputerName
属性。
,...n
指示 可以多次查询event_property ,用逗号分隔。
*
指定对与事件关联的所有属性进行查询。
event_type
可针对其创建事件通知的任何事件。 有关可用事件的列表,请参阅 适用于服务器事件类和属性的 WMI 提供程序。 请注意,事件类型名称对应于使用 CREATE EVENT NOTIFICATION 手动创建事件通知时可以指定的相同event_type | event_group。 事件类型的示例包括CREATE_TABLE、LOCK_DEADLOCK、DDL_USER_EVENTS和TRC_DATABASE。
注意
执行 DDL 式操作的某些系统存储过程也可以激发事件通知。 测试您的事件通知以确定它们是否响应运行的系统存储过程。 例如,CREATE TYPE 语句和 sp_addtype 存储过程都将触发在CREATE_TYPE事件上创建的事件通知。 但是, sp_rename 存储过程不会触发任何事件通知。 有关详细信息,请参阅DDL 事件。
where_condition
WHERE 子句查询谓词由event_property名称和逻辑和比较运算符组成。 where_condition确定在目标数据库中注册相应事件通知的范围。 它还可以充当筛选器来定位要从中查询 event_type的特定架构或对象。 有关详细信息,请参阅本主题后面的“备注”部分。
只有 =
操作数可与 DatabaseName
、SchemaName
和 ObjectName
一起使用。 其他表达式不能与这些事件属性一起使用。
注解
WMI Provider for Server Events 语法的where_condition确定以下内容:
提供程序尝试检索指定 event_type的范围:服务器级别、数据库级别或对象级别(当前唯一支持的对象是队列)。 最后,此范围用于确定在目标数据库中创建的事件通知的类型。 这个过程称为事件通知注册。
要在其上进行注册的数据库、架构和对象(视具体情况而定)。
WMI Provider for Server Events 使用从下到上的最先适应算法为基础 EVENT NOTIFICATION 生成尽可能小的范围。 该算法尝试最大程度地减少服务器上的内部活动以及 SQL Server 实例与 WMI 主机进程之间的网络流量。 提供程序检查 FROM 子句中指定的event_type 以及 WHERE 子句中的条件,并尝试将基础 EVENT NOTIFICATION 注册到尽可能窄的范围。 如果提供程序无法在最小的范围内注册,则它会依次尝试在更大的范围内注册,直到注册最终成功为止。 如果它达到服务器级别的最大范围且失败,则它将向使用者返回一个错误。
例如,如果在 WHERE 子句中指定了 DatabaseName='AdventureWorks'**,则提供程序会尝试在 AdventureWorks2012 数据库中注册事件通知。 如果 AdventureWorks2012 数据库存在,并且调用客户端具有在 AdventureWorks2012 中创建事件通知所需的权限,则注册成功。 否则,将尝试在服务器级别注册事件通知。 如果 WMI 客户端拥有所需的权限,则注册成功。 但是,在此方案中,在创建 AdventureWorks2012 数据库之前,事件不会返回到客户端。
where_condition还可以充当筛选器,以将查询额外限制为特定的数据库、架构或对象。 例如,请考虑下列 WQL 查询:
SELECT * FROM ALTER_TABLE
WHERE DatabaseName = 'AdventureWorks' AND SchemaName = 'Sales'
AND ObjectType='Table' AND ObjectName = 'SalesOrderDetail'
根据注册过程的结果的不同,可以在数据库级别或服务器级别注册此 WQL 查询。 但是,即使此查询的注册是在服务器级别进行的,提供程序最终还是会筛选不适用于 ALTER_TABLE
表的所有 AdventureWorks.Sales.SalesOrderDetail
事件。 也就是说,提供程序只会返回在此特定表上出现的 ALTER_TABLE
事件的属性。
如果指定复合表达式,例如 DatabaseName='AW1'
OR DatabaseName='AW2'
,则会尝试在服务器范围注册单个事件通知,而不是两个独立的事件通知。 如果调用客户端拥有权限,则注册成功。
如果在SchemaName='X' AND ObjectType='Y' AND ObjectName='Z'
子句中WHERE
全部指定,则尝试直接在架构X
中的对象Z
上注册事件通知。 如果客户端拥有权限,则注册成功。 请注意,目前,对象级事件仅在队列上受支持,并且仅支持QUEUE_ACTIVATION event_type。
请注意,并非所有事件均可在任何特定的范围内进行查询。 例如,针对跟踪事件(例如 Lock_Deadlock)或跟踪事件组(例如 TRC_LOCKS)的 WQL 查询仅可在服务器级别进行注册。 与此类似,CREATE_ENDPOINT 事件和 DDL_ENDPOINT_EVENTS 事件组也只能在服务器级别进行注册。 有关注册事件的适当范围的详细信息,请参阅 “设计事件通知”。 尝试注册一个 WQL 查询,其 event_type 只能在服务器级别注册,始终在服务器级别进行注册。 如果 WMI 客户端拥有权限,则注册成功。 否则,将向客户端返回一个错误。 不过,在某些情况下,仍可根据与服务器级别事件对应的属性将 WHERE 子句用作服务器级别事件的筛选器。 例如,许多跟踪事件具有可在 WHERE 子句中用作筛选器的 DatabaseName
属性。
服务器范围的事件通知是在 master 数据库中创建的,可以使用sys.server_event_notifications目录视图查询元数据。
数据库范围或对象范围内的事件通知是在指定的数据库中创建的,可以使用sys.event_notifications目录视图查询元数据。 (您必须为目录视图加上对应的数据库名前缀。)
示例
A. 在服务器范围查询事件
以下 WQL 查询检索 SQL Server 实例上发生的任何 SERVER_MEMORY_CHANGE
跟踪事件的所有事件属性。
SELECT * FROM SERVER_MEMORY_CHANGE
B. 在数据库范围查询事件
以下 WQL 查询检索在 AdventureWorks
数据库中出现且存在于 DDL_DATABASE_LEVEL_EVENTS
事件组下的任何事件的特定事件属性。
SELECT SPID, SQLInstance, DatabaseName FROM DDL_DATABASE_LEVEL_EVENTS
WHERE DatabaseName = 'AdventureWorks'
°C 在数据库范围查询事件,并按架构和对象进行筛选
以下查询检索在表 ALTER_TABLE
上出现的任何 AdventureWorks.Sales.SalesOrderDetail
事件的所有事件属性。
SELECT * FROM ALTER_TABLE
WHERE DatabaseName = 'AdventureWorks' AND SchemaName = 'Sales'
AND ObjectType='Table' AND ObjectName = 'SalesOrderDetail'