SqlDependency有什么限制

我正在使用一个表作为消息队列,并通过使用SqlDependency“注册”了更新。 我读到的每个人都在说要注意它的局限性,而不是特别说明它们是什么。 从我收集的信息来看,当桌子的更新频率非常高时,会有问题,幸运的是我只能看到每分钟最多10-20个值。

SqlServer的其他限制/影响是什么?

我能find的最完整的清单如下:

  • 必须明确声明SELECT语句中的投影列,并且表名必须由两部分名称限定。 请注意,这意味着在语句中引用的所有表必须位于同一个数据库中。
  • 该语句可能不使用星号( )或表名。 语法来指定列。
  • 该声明可能不使用未命名的列或重复的列名称。
  • 该语句必须引用基表。
  • 该声明不得引用具有计算列的表格。
  • 除非语句使用GROUP BYexpression式,否则SELECT语句中的投影列可能不包含聚合expression式。 当提供GROUP BYexpression式时,select列表可能包含集合函数COUNT_BIG()或SUM()。 但是,可能不会为可空列指定SUM()。 该声明可能不指定HAVING,CUBE或ROLLUP。
  • 用作简单expression式的SELECT语句中的投影列不能多次出现。
  • 该声明不得包含PIVOT或UNPIVOT运营商。
  • 该声明不得包含UNION,INTERSECT或EXCEPT运算符。
  • 声明不得引用视图。
  • 该语句不得包含以下任何一项:DISTINCT,COMPUTE或COMPUTE BY或INTO。
  • 该语句不得引用服务器全局variables(@@ variable_name)。
  • 该语句不得引用派生表,临时表或表variables。
  • 该声明不得引用来自其他数据库或服务器的表或视图。
  • 该语句不得包含子查询,外连接或自连接。
  • 该语句不得引用大对象types:text,ntext和image。
  • 该语句不得使用CONTAINS或FREETEXT全文谓词。
  • 该语句不得使用行集函数,包括OPENROWSET和OPENQUERY。
  • 该语句不得使用以下任何聚合函数:AVG,COUNT(*),MAX,MIN,STDEV,STDEVP,VAR或VARP。
  • 声明不得使用任何不确定的函数,包括sorting和窗口函数。
  • 该语句不得包含用户定义的聚合。
  • 该声明不得引用系统表或视图,包括目录视图和dynamicpipe理视图。
  • 该声明不得包含FOR BROWSE信息。
  • 该声明不得引用队列。
  • 该语句不得包含无法更改且无法返回结果的条件语句(例如,WHERE 1 = 0)。
  • 该语句不能指定READPASTlocking提示。
  • 该声明不得引用任何Service Broker QUEUE。
  • 该声明不得引用同义词。
  • 该声明不得基于双/实数据types进行比较或expression。
  • 该声明不得使用TOPexpression式。

还有一些额外的信息:

  • 了解SQL依赖关系
  • 使用查询通知

除此之外,对于其他人想使用SqlDependency来接收有关更改的通知,我一直在使用这种方法在生产中,我发现它的问题。 我正在调查,看看问题是否与我的代码有关,但主要问题是:

  • 如果您连续发生多个更改,则不会始终获得与代码相同的事件数量。 在我的代码中,如果一个接一个地插入2个新logging,我只会得到一个通知(最后一个)。

  • 没有办法知道添加的logging。 因此,如果添加新logging,并且代码触发以接收通知,则代码中无法知道该新logging的标识,因此您需要为其查询数据库。

花了一天的时间追溯SQL Service Broker不工作的问题,根本原因是在存储过程中引用数据库。

例如,这个select在SQL Management Studio中工作正常:

 select [MyColumn] from [MyDatabase].[MySchema].[MyTable] 

但是,这被SQL Service Broker拒绝,因为我们在select语句中引用数据库,并且SqlDependency的callback在SqlNotificationEventArgs e返回Invalid ,请参阅http://msdn.microsoft.com/en-us/library/ ms189308.aspx 。

将传递给SqlDependency的SQL更改为以下语句消除了以下错误:

 select [MyColumn] from [MySchema].[MyTable] 

更新

上面的例子只是SQL Service Broker依赖的SQL语句的许多限制之一。 有关限制的完整列表,请参阅SqlDependency的限制 。

原因? SQL Service Broker使用的SQL语句在幕后转换为监视SQL事务日志以更改数据库的指令。 这个监视是在SQL Server的核心中执行的,当检测到对表的更改时,它使得它非常快速。 但是,这个速度是有代价的:你不能只使用任何SQL语句,你必须使用一个可以转换成指令来监视SQL事务日志的语句。

请注意,您不能在存储过程中使用nolock提示,否则依赖项将始终无效,因此您在其上创build的任何caching都将永久性地重新查询数据库。

 with (NOLOCK) 

这似乎没有在文档中提到(据我所知)

在过程脚本之前需要以下SET选项

 SET ANSI_NULLS ON SET ANSI_PADDING ON SET ANSI_WARNINGS ON 

其他人争辩说,这些SET选项也是必需的,但我不认为它们是。 无论如何,这是一个好主意。

 SET CONCAT_NULL_YIELDS_NULL ON SET QUOTED_IDENTIFIER ON SET NUMERIC_ROUNDABORT OFF SET ARITHABORT ON 

我有这个技术的另一个大问题:需要订阅者连接具有创build过程权限。 此时我的应用程序的Web服务层作为受限用户运行。 要使用SQLDependency获取通知设置,我必须打开该用户来创build特效。 这听起来像是在获得拥有的道路上相当不错的一步。

为了克服这些限制,你可以尝试使用SqlTableDependency。 看看www.sqltabledependency.it