SQL Сервер: функция работает в одном представлении, возвращает ошибку разрешения в другом - PullRequest
0 голосов
/ 08 мая 2020

У нас есть простая функция, которая считает рабочие дни между двумя датами (исключая выходные и праздничные дни).

В одном представлении он работает нормально, но в другом представлении возвращает:

В разрешении EXECUTE было отказано в объекте 'fx_CountDaysBetween_V2', базе данных 'xxxx', схеме 'dbo'

Хорошее представление вызывает функцию с этой строкой

CASE 
   WHEN r.Current_Status_Code IN (2, 3, 4, 7) 
      THEN dbo.fx_CountDaysBetween_V2(CONVERT(DATE, PA.Create_Date), CONVERT(DATE, GETUTCDATE())) ELSE NULL END AS DaysInQueue,

Плохое представление имеет следующее:

dbo.fx_CountDaysBetween_V2(CONVERT(DATE, rh.Submitted_Date), ISNULL(CONVERT(DATE, rc.Completed_Date), GETUTCDATE())) AS SLA,

Человек с проблемой НЕ имеет прав на выполнение. Это похоже на проблему, но тогда почему одно работает, а другое нет. Эта функция также без проблем используется в других областях / представлениях

1 Ответ

0 голосов
/ 09 мая 2020

У хорошего и плохого вида один и тот же владелец? Если нет, я бы подозревал, что это связано с цепочкой владения - посмотрите на https://docs.microsoft.com/en-us/sql/relational-databases/tutorial-ownership-chains-and-context-switching?view=sql-server-ver15

или

https://www.mssqltips.com/sqlservertip/1778/ownership-chaining-in-sql-server-security-feature-or-security-risk/

для полного объяснения, но в основном, если вы даете пользователю разрешения на объект, такой как представление или хранимая процедура, владелец передает это разрешение другим вещам тем же владельцем.

Если это не то, что происходит изучите цепочку зависимостей (фактически стек вызовов), чтобы увидеть, было ли переключение контекста пользователя между тем, где пользователь впервые начинает делать запрос, и вызовом dbo.fx_CountDaysBetween. Найдите «EXECUTE AS» в одном из представлений / функций / чего угодно. Обратите внимание, что это может быть отдельный оператор или часть определения, поэтому его может быть трудно обнаружить.

Это 2 наиболее распространенные причины, о которых я могу думать, если это ни один из тех комментариев по этому поводу и обновите свое сообщение, включив в него информацию о владельце и, возможно, вставьте оператор регистрации для записи текущего пользовательского контекста непосредственно перед вызовом.

...