Якщо ви хочете, щоб користувачі вибирали з перегляду, чому ви надаєте таблицю? Під "відкликати" ви маєте на увазі явну відкликання / заперечення? Заборонити буде перекривати грант, тож у вас є проблема ... ви повинні мати можливість це додати, додавши грант у подання, і нічого не роблячи на столах.
Ось короткий приклад, коли 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;
Результати:
Msg 229, рівень 14, стан 5, рядок 1
В дозволі SELECT було відмовлено на об'єкті 't1', базі даних 'd1', схемі 'dbo'.
Msg 229, рівень 14, стан 5, рядок 3
В дозволі SELECT було відмовлено на об'єкті 't2', базі даних 'd2', схемі 'dbo'.