我在使用自定义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.
那么可以在索引视图中使用自定义聚合函数吗?我找不到任何关于此的文件...
答案 0 :(得分:7)
Creating Indexed Views上的页面列出了许多限制:
视图中的SELECT语句不能包含以下Transact-SQL语法元素:
...
CLR用户定义的聚合函数。
目前还没有规定将CLR聚合描述为确定性(至少,如果API将是一致的)。 SqlFunctionAttribute具有IsDeterministic
属性。 SqlUserDefinedAggregateAttribute
如果您考虑为什么索引视图存在如此多的限制,那么对事情进行推理会有所帮助。
聚合上的那些解释非常简单 - 您只能使用具有SQL Server能够调整值的属性的聚合(例如SUM
和COUNT_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如何希望与用户定义的聚合实现类似的功能呢?用户定义的聚合的当前接口没有您需要的那种支持(它也需要像接口一样具有触发器)。