Доступ к данным в определенных пользователем агрегатах SQLCLR (UDA)

Я понимаю ограничения SQLCLR Aggregates в том, что касается доступа к данным. Сказав это, есть ли способ (обходной путь) для сохранения результатов в таблице? Он должен быть в агрегатах SQLCLR.

2 ответа

Решение

Зачем вам нужно сохранять агрегированный результат в таблице внутри пользовательского агрегата (UDA)? Это не имеет особого смысла, учитывая, что вы можете сохранить результаты в таблице, используя обычный T-SQL:

INSERT INTO SchemaName.TableName (Col1, Col2, ...)
  SELECT tab.SomeColumn, SchemaName.CustomAggregate(tab.OtherColumn)
  FROM   SchemaName.TableName tab
  GROUP BY tab.SomeColumn;

По сути, это работает так же, как если бы вы хранили результаты любой из встроенных агрегатных функций, таких как: SUM, MIN, MAX, COUNT, AVG, так далее.

ОДНАКО, если вам нужно было сделать это по какой-то странной причине, просто используйте внешнее соединение (т.е. не Context Connection = true;) в Terminate() Метод УДА.

Обращаем ваше внимание на то, что обязательным условием для такого доступа к данным является то, что соединение не пытается подключиться к текущему контексту транзакции (а привлечение является поведением по умолчанию). Это означает, что в строке подключения должно быть указано следующее ключевое слово и значение: Enlist = false;, И это работает, так как я успешно использовал следующее в Terminate() метод, и до добавления Enlist=false; Я также получал " Доступ к данным не разрешен в этом контексте. Либо контекст является функцией или методом, не помеченным DataAccessKind.Read, либо SystemDataAccessKind.Read, является обратным вызовом для получения данных из метода FillRow функции с табличной функцией, или является методом проверки UDT. "ошибка.

using (SqlConnection _Connection =
                    new SqlConnection("Trusted_Connection=true; Enlist=false;"))
{
    using (SqlCommand _Command = _Connection.CreateCommand())
    {
        _Command.CommandText = "SELECT TOP 1 * FROM sys.objects;";
        _Connection.Open();
        _Command.ExecuteNonQuery();
    }
}

Также обратите внимание, что для выполнения обычного / внешнего подключения требуется, чтобы сборка была помечена как EXTERNAL_ACCESS, Однако это не требует, чтобы база данных была установлена ​​на TRUSTWORTHY ON: вы просто подписываете сборку, создаете асимметричный ключ в master из этой DLL / Assembly создайте Login из этого асимметричного ключа и, наконец, GRANT этот логин EXTERNAL ACCESS ASSEMBLY разрешение.

Когда у вас есть результаты агрегирования в функции C#, почему бы вам не использовать C# ADO.NET (для операций с базой данных) для хранения этих агрегатов в базе данных. Это будет в вашей функции SQL CLR, так что вы вызовете функцию SQL CLR один раз из базы данных, и она сохранит агрегаты в некоторой таблице.

Другие вопросы по тегам