Я использую контекстное соединение в скалярной функции SQL CLR. Функция создает динамический запрос, а затем выполняет его (получая данные/логику из разных мест для построения запроса).
Я могу «построить» динамическую строку вручную и запустить ее в стандартном окне Management Studio, и она работает нормально. Когда тот же запрос выполняется через CLR в контекстном соединении, я получаю сообщение об ошибке.
Я отладил эту вещь и обнаружил, что ошибка связана с проблемой разрешения на UDF TSQL, который вызывается в запросе. Созданное сообщение об ошибке:
Отказано в разрешении EXECUTE на be.udfDivide
Я знаю, что у меня есть доступ к этой определяемой пользователем функции, потому что она работает, когда я запускаю запрос вручную, но при запуске через SQLCLR происходит сбой, хотя код SQLCLR должен выполняться в моем контексте.
Запрос эффективно:
select be.udfDivide(sum(Numerator), sum(Denominator))
from Table where <some stuff>
В <some stuff> живет вся сложная логика, но я уверяю вас, что это просто предложение where, и эта функция CLR успешно запускается миллионы раз в день, когда в запросе нет ссылки на UDF.
С помощью некоторого творческого взлома запросов я смог подтвердить, что контекстное соединение выполняется под правильным пользователем (как SYSTEM_USER, так и CURRENT_USER), и я знаю, что у этого пользователя есть разрешения на UDF. Таким образом, похоже, что причиной этого является нарушение цепочки владения. Только пока не знаю, как это исправить.
Я знаю, что могу удалить UDF в этом конкретном случае, так как это простое деление (хотя UDF обрабатывает деление на ноль для нас), но в случае более сложных UDF мы хотели бы иметь возможность ссылаться на них в запросе.
Функция be.udfDivide приведена ниже для справки:
ALTER function [be].[udfDivide](@Numerator float, @Demoninator float,
@ValueIfDivideByZero float)
returns float
as
begin
declare @result float
if @Demoninator = 0
begin set @result = @ValueIfDivideByZero end
else
begin set @result = @Numerator / @Demoninator end
return @result
end