SQL Server 2008:自定义聚合函数和索引视图

时间:2011-08-15 12:21:35

标签: sql-server sql-server-2008 sqlclr

我在使用自定义CLR聚合函数的视图上创建索引时遇到问题。

我没有看到任何方法将聚合函数标记为确定性或使用模式绑定。

我正在创建我的函数:

CREATE ASSEMBLY StringUtil
AUTHORIZATION dbo
FROM 'C:\StringUtil.dll'
WITH PERMISSION_SET = UNSAFE
GO

CREATE AGGREGATE SUMSTRING (@input nvarchar(200)) 
RETURNS nvarchar(max) WITH SCHEMABINDING 
EXTERNAL NAME StringUtil.Concatenate

我的观点定义为:

CREATE VIEW RolledValues WITH SCHEMABINDING
AS
SELECT ID, SumString(ValueText) as Value FROM [dbo].[IDValue]
GROUP BY ID

当我尝试在该视图上创建索引时会出现问题:

CREATE UNIQUE CLUSTERED INDEX IDX_RollValues_ID_VALUE on RolledValues (ID)

Error:  Cannot create index on view "dbo.RolledValues" because it uses aggregate
"dbo.SumString". Consider eliminating the aggregate, not indexing the view, or 
using alternate aggregates.

那么可以在索引视图中使用自定义聚合函数吗?我找不到任何关于此的文件...

1 个答案:

答案 0 :(得分:7)

Creating Indexed Views上的页面列出了许多限制:

  

视图中的SELECT语句不能包含以下Transact-SQL语法元素:

     

...

     

CLR用户定义的聚合函数。

目前还没有规定将CLR聚合描述为确定性(至少,如果API将是一致的)。 SqlFunctionAttribute具有IsDeterministic属性。 SqlUserDefinedAggregateAttribute

中不存在此类属性

如果您考虑为什么索引视图存在如此多的限制,那么对事情进行推理会有所帮助。

聚合上的那些解释非常简单 - 您只能使用具有SQL Server能够调整值的属性的聚合(例如SUMCOUNT_BIG) ,或者在作为当前事务主题的行子集上基于在索引中添加或删除行。

E.g。如果视图的行ID = 19,COUNT_BIG = 5,SUM = 96,则事务将删除3行ID 19,其{{1添加到43,然后它可以将视图的该行更新为SUM = 2和COUNT_BIG = 53。或者,如果事务已删除5行且SUM = 19,则会导致删除该行。

请注意,在任何一种情况下,我们都不必检查表的任何其他行,以确定它们是否ID = 19。

那么SQL Server如何希望与用户定义的聚合实现类似的功能呢?用户定义的聚合的当前接口没有您需要的那种支持(它也需要像接口一样具有触发器)。