定义条件操作
更新日期: 2006 年 7 月 17 日
操作是指每次 Notification Services 触发订阅规则时运行的一组 Transact-SQL 语句。每条订阅规则可包含一项操作,即基本操作或条件操作,前者为预定义的查询,后者允许订阅方为通知生成查询定义等效的 WHERE 子句。本主题介绍了条件操作及如何编写这些操作。
重要提示: |
---|
只有当您需要允许订阅方创建其自己的复杂条件以生成通知时才使用条件操作。否则,使用允许用户为参数化查询输入值的预定义操作更为有效。有关详细信息,请参阅定义操作。 |
条件操作
条件操作允许订阅方创建灵活的规则。预定义操作仅允许订阅方为开发人员定义的查询指定参数值,而条件操作则允许订阅方通过使用布尔运算符(AND、OR 和 NOT)组合各个条件,为查询创建等效的 WHERE 子句。
例如,天气应用程序可能拥有包含以下两个字段的事件类:“城市”和“天气预报”****。开发人员可定义基本查询来创建通知,如下所示:
INSERT INTO dbo.WeatherNotifications(SubscriberId, DeviceName,
SubscriberLocale, City, Forecast)
SELECT [Subscription.SubscriberId], [Subscription.DeviceName],
[Subscription.SubscriberLocale], [Input.City], [Input.Forecast])
FROM dbo.FlightEventRule
请注意,此操作会从与规则(在本例中为 FlightEventRule)同名的视图中选择数据。该视图中的字段名称为 Subscription.SubscriptionFieldName 和 Input.EventFieldName,字段名称要求用方括号括起来。
通过订阅管理界面,订阅方可以定义相当于 WHERE 子句的条件。例如,用户可以指定两个条件:“城市”为“西雅图”,“天气预报”包含“雪”,然后使用 AND 运算符将这些条件联接在一起。这相当于下列 WHERE 子句:
WHERE City = 'Seattle' AND Forecast LIKE '%snow%'
当 Notification Services 运行订阅规则时,它会将所有类似的条件一起进行处理,从而提高性能。然后,Notification Services 会使用匹配的输入和订阅对来填充该规则的视图。
性能注意事项
即使 Notification Services 将所有类似的条件一起进行处理,但在使用条件操作时仍存在一定的开销。Notification Services 必须获取所有条件集,组织各种条件以有效进行评估,对这些条件进行求值,然后为所有订阅生成结果通知。由于存在这一开销,因此评估使用条件操作的规则所需的时间通常比评估预定义操作所需的时间更长。
安全性
所有条件操作均在您为条件操作指定的数据库用户上下文中执行。使用低特权的用户可最大限度地降低安全隐患,以防任何人危及订阅管理界面的安全以及插入尝试访问其他表或执行其他操作的条件。
数据库用户应具备受限权限,使用户只能从事件源中选择数据以及只能执行条件所使用的用户定义函数。
当 Notification Services 在应用程序数据库中创建应用程序对象时,与此用户关联的 SQL Server 登录帐户必须存在。
事务
条件操作中的所有语句都是同一个事务的一部分,因此它们要么全部成功完成,要么全部被回滚。如果事务失败,则 Notification Services 会将错误写入 Windows 应用程序日志。
定义条件操作
如果您通过 XML 定义应用程序,请在该应用程序定义文件 (ADF) 中定义条件操作。如果以编程方式定义应用程序,请使用 Notification Services 管理对象 (NMO) 来定义条件操作。
定义条件操作
- ConditionAction Element (ADF)
- Microsoft.SqlServer.Management.Nmo.SubscriptionClass.SubscriptionConditionEventRules 属性 (NMO)
- Microsoft.SqlServer.Management.Nmo.SubscriptionClass.SubscriptionConditionScheduledRules 属性 (NMO)
SQL Server 登录
由于 Notification Services 在指定数据库用户的上下文中运行所有条件操作,因此您必须指定与该用户关联的登录帐户。在 Notification Services 创建应用程序之前,该登录帐户必须已经存在。如果登录帐户不存在,则 Notification Services 在尝试创建应用程序时会失败,并将回滚实例创建或实例更新。
确保登录帐户对服务器具有受限权限。登录帐户最好不具备任何服务器范围的权限,也不属于任何服务器角色。
定义 SQL Server 登录
- SqlLogin Element (ADF)
- Microsoft.SqlServer.Management.Nmo.SubscriptionConditionEventRule.SqlLoginName 属性 (NMO)
- Microsoft.SqlServer.Management.Nmo.SubscriptionConditionScheduledRule.SqlLoginName 属性 (NMO)
数据库用户
数据库用户是运行所有条件操作所使用的帐户。Notification Services 将运行条件操作所需的部分权限授予此数据库用户。如果在 Notification Services 创建应用程序时,数据库用户不存在,则 Notification Services 同时会创建数据库用户。
Notification Services 将授予对 Notification Services 对象所需的权限,但不会授予对输入表或视图的权限,也不会授予对条件操作所使用的任何用户定义函数的权限。您需要在部署应用程序时授予这些权限。用于授予这些权限的 Transact-SQL 命令的格式如下:
-- grant permissions on the view for an input event class
GRANT SELECT ON ApplicationSchema.EventClassName TO SqlUserAccount
-- grant permissions on an input event chronicle table
GRANT SELECT ON ChronicleSchema.ChronicleName TO SqlUserAccount
-- grant execute permissions on a user-defined function
-- used in Subscription.Conditions
GRANT EXEC ON UDFSchema.MyUserDefinedFunction TO SqlUserAccount
定义数据库用户
- SqlUser Element (ADF)
- Microsoft.SqlServer.Management.Nmo.SubscriptionConditionEventRule.SqlUserName 属性 (NMO)
- Microsoft.SqlServer.Management.Nmo.SubscriptionConditionScheduledRule.SqlUserName 属性 (NMO)
输入名称
在使用条件操作时,必须指定哪个视图或表包含事件数据。
- 如果条件操作采用事件规则,则输入通常为事件视图,其名称与事件类相同。
注意 不要将名为 NSEventClassNameEvents 的事件表用作输入。此表包含所有尚未从系统中删除并将导致重复通知的事件。 - 如果条件操作支持计划规则,则输入通常为事件历史记录。
注意 对于预定规则,不要将名为 EventClassName 的事件视图用作输入。此视图仅包含当前的事件批,并且对于预定规则而言经常为空或不完整。
定义输入名称
- InputName Element (ADF)
- Microsoft.SqlServer.Management.Nmo.SubscriptionConditionEventRule.InputTypeName 属性 (NMO)
- Microsoft.SqlServer.Management.Nmo.SubscriptionConditionScheduledRule.InputTypeName 属性 (NMO)
输入架构
输入架构是输入的数据库架构名称。
- 如果输入为事件视图,则架构为应用程序架构。应用程序架构可以在定义应用程序数据库时进行定义,也可以取默认值 dbo。有关详细信息,请参阅定义应用程序数据库。
- 如果输入为事件历史记录,则在创建事件历史记录的 CREATE TABLE 语句中定义架构。这通常与应用程序架构相同。有关详细信息,请参阅为事件类定义历史记录。
定义输入架构
- InputSchema Element (ADF)
- Microsoft.SqlServer.Management.Nmo.SubscriptionConditionEventRule.InputTypeSchema 属性 (NMO)
- Microsoft.SqlServer.Management.Nmo.SubscriptionConditionScheduledRule.InputTypeSchema 属性 (NMO)
Transact-SQL 表达式
每项历史记录操作均指定了用于生成通知的核心查询。该查询指定了选择订阅和输入字段并将其添加到通知表中的查询。
该查询必须从联接订阅与事件数据的视图中选择订阅和输入字段。视图中订阅字段的名称格式为 [Subscription.SubscriptionFieldName]。输入(事件)字段的名称格式为 [Input.EventFieldName]。
订阅方通过订阅管理界面为查询创建等效的 WHERE 子句。Notification Services 将评估所有相关订阅的条件操作,然后生成通知。
模板
下面的 Transact-SQL 模板演示如何为条件操作编写 Transact-SQL 表达式。
INSERT INTO schema.NotificationClassName(SubscriberId,
DeviceName, SubscriberLocale, NotificationFields)
SELECT [Subscription.SubscriberId], DeviceName, SubscriberLocale,
[Input.EventFieldName], ...
FROM schema.RuleName
在 SELECT 语句中,您可以从数据源(如与规则同名的视图)选择 DeviceName 和 SubscriberLocale 值,也可以提供文字值,如“File”和“en-US”。
查询可包含其他语句,并且不需要生成通知。查询可根据需要执行任何任务,如维护历史记录。但是,应至少有一个订阅规则可生成通知。否则,您的应用程序将不会生成通知并将通知分发给订阅方。
INSERT 子句
如模板中所示,您必须在 INSERT 语句中按下列顺序指定下列字段:
- SubscriberId
- DeviceName
- SubscriberLocale
所有非计算字段均在通知架构中定义。如果使用计算字段,则不要将值添加到这些字段。在插入通知数据时对这些值进行计算。
请注意,SubscriberId 和 DeviceName 值必须与 SubscriberDevices 表中的记录匹配。
仅添加到订阅规则内的通知表。当处理订阅规则时,Notification Services 将准备每个规则触发,接着触发规则,然后在规则触发之后执行清理操作。如果尝试将通知插入订阅规则触发之外的通知表中,则不执行准备和清理操作,这样会导致失败。
使用存储过程
您可以调用存储过程,而不是在条件操作中嵌入 Transact-SQL 语句。必须在应用程序数据库中创建存储过程。还可以在部署脚本中定义存储过程。您应在 Notification Services 创建实例或添加应用程序之后,但在启用实例或应用程序之前创建存储过程。
若要使用存储过程,请用对存储过程的调用来替换查询文本。下面的示例演示如何调用存储过程:
EXECUTE dbo.WeatherConditionActionSP;
定义 Transact-SQL 表达式
- SqlExpression Element for ConditionAction (ADF)
- Microsoft.SqlServer.Management.Nmo.SubscriptionConditionEventRule.SqlExpression 属性 (NMO)
- Microsoft.SqlServer.Management.Nmo.SubscriptionConditionScheduledRule.SqlExpression 属性 (NMO)
编写订阅管理界面
编写订阅管理界面时,必须考虑应用程序所支持的订阅类型。对于基于条件的订阅,订阅管理界面必须允许订阅方输入条件,例如从下拉框选择一个字段、输入一个运算符以及提供一个值。
有关展示如何添加基于条件的订阅的示例代码,请参阅添加订阅。
请参阅
参考
Microsoft.SqlServer.NotificationServices.Rules
概念
其他资源
INSERT (Transact-SQL)
SELECT (Transact-SQL)
定义订阅类
开发订阅管理界面
帮助和信息
更改历史记录
发布日期 | 历史记录 |
---|---|
2006 年 7 月 17 日 |
|