Доступ к данным в определенных пользователем агрегатах 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 один раз из базы данных, и она сохранит агрегаты в некоторой таблице.