Если вы хотите, чтобы пользователи выбирали из представления, почему вы предоставляете эту таблицу? Под «отзывать» вы подразумеваете явное «отозвать / отрицать»? Запрет будет отменять грант, так что есть ваша проблема ... вы должны быть в состоянии сделать это, добавив грант в представление и ничего не делая в любом случае с таблицами.
Вот быстрый пример, где SELECT
явно не предоставлено на столе, но было на представлении. Пользователь может выбирать из вида, но не из таблицы.
CREATE USER foo WITHOUT LOGIN;
GO
CREATE TABLE dbo.a(id INT);
CREATE TABLE dbo.b(id INT);
GO
CREATE VIEW dbo.v
AS
SELECT a.id FROM a INNER JOIN b ON a.id = b.id;
GO
GRANT SELECT ON dbo.v TO foo;
GO
EXECUTE AS USER = N'foo';
GO
-- works:
SELECT id FROM dbo.v;
GO
-- Msg 229, SELECT denied:
SELECT id FROM dbo.a;
GO
REVERT;
Обратите внимание, что это предполагает, foo
что не было предоставлено повышенных привилегий через явные разрешения на схему или базу данных, или через роль или членство в группе.
Поскольку вы используете таблицы в нескольких базах данных (извините, я пропустил конец первого предложения вначале), вам также могут потребоваться явные разрешения для таблиц в базе данных, где представление не существует. Чтобы избежать предоставления выбора таблицам, вы можете создать представление в каждой базе данных, а затем объединить представления.
Создайте две базы данных и логин:
CREATE DATABASE d1;
GO
CREATE DATABASE d2;
GO
USE [master];
GO
CREATE LOGIN blat WITH PASSWORD = 'x', CHECK_POLICY = OFF;
GO
В базе данных d1
создайте пользователя, затем создайте таблицу и простое представление для этой таблицы. Предоставить пользователю право выбора только для просмотра:
USE d1;
GO
CREATE USER blat FROM LOGIN blat;
GO
CREATE TABLE dbo.t1(id INT);
GO
CREATE VIEW dbo.v1
AS
SELECT id FROM dbo.t1;
GO
GRANT SELECT ON dbo.v1 TO blat;
GO
Теперь, во второй базе данных, создайте пользователя, затем создайте другую таблицу и представление, которое присоединяет эту таблицу к представлению в d1
. Предоставить выбор только для просмотра.
USE d2;
GO
CREATE USER blat FROM LOGIN blat;
GO
CREATE TABLE dbo.t2(id INT);
GO
CREATE VIEW dbo.v2
AS
SELECT v1.id FROM dbo.t2
INNER JOIN d1.dbo.v1 AS v1
ON t2.id = v1.id;
GO
GRANT SELECT ON dbo.v2 TO blat;
GO
Теперь запустите новое окно запроса и измените учетные данные для входа в систему blat
( EXECUTE AS
здесь не работает). Затем запустите следующее из контекста любой базы данных, и оно должно работать нормально:
SELECT id FROM d1.dbo.v2;
Оба должны дать Msg 229 ошибок:
SELECT id FROM d1.dbo.t1;
GO
SELECT id FROM d2.dbo.t2;
Результаты:
Сообщение 229, уровень 14, состояние 5, строка 1
Отказано в разрешении SELECT для объекта «t1», базы данных «d1», схемы «dbo».
Сообщение 229, уровень 14, состояние 5, строка 3
Отказано в разрешении SELECT для объекта «t2», базы данных «d2», схемы «dbo».