SQL Server 2008: пользовательские агрегатные функции и индексированные представления - PullRequest
3 голосов
/ 15 августа 2011

У меня проблемы с созданием индекса для представления, в котором используется настраиваемая агрегатная функция 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 Ответ

7 голосов
/ 15 августа 2011

Страница на Создание индексированных представлений содержит ряд ограничений:

Оператор SELECT в представлении не может содержать следующие элементы синтаксиса Transact-SQL:

...

Определяемая пользователем агрегатная функция CLR.

В настоящее время нет даже возможности описывать агрегат CLR как детерминированный (по крайней мере, если API будет согласованным). Атрибут SqlFunctionAttribute имеет свойство IsDeterministic. Нет такого свойства в SqlUserDefinedAggregateAttribute


Полезно рассуждать о вещах, если учесть, почему существует так много ограничений для индексированных представлений.

Те, что в агрегатах, имеют довольно простое объяснение - вам разрешено использовать только агрегаты (например, SUM и COUNT_BIG), обладающие свойством, что SQL Server сможет корректировать значения или добавлять или удалить строки из индекса на основе чисто из подмножества строк, являющихся предметом текущей транзакции.

например. если у представления есть строка с ID = 19, COUNT_BIG = 5 и SUM = 96, и транзакция удаляет 3 строки с ID 19, чье значение SUM добавляет к 43, тогда оно может обновить эта строка вида будет COUNT_BIG = 2 и SUM = 53. Кроме того, если бы транзакция удалила 5 строк с ID = 19, это привело бы к удалению строки.

Обратите внимание, что в любом случае нам не нужно проверять какие-либо другие строки таблицы, чтобы определить, имеют ли они ID = 19.

Так как же SQL Server может надеяться на достижение аналогичной функциональности с помощью пользовательского агрегата? Текущий интерфейс для определенных пользователем агрегатов не имеет необходимой вам поддержки (ему также потребуется интерфейс типа триггера).

...