Jika Anda ingin pengguna memilih dari tampilan, mengapa Anda memberikan ke meja? Maksud "mencabut" maksud Anda secara eksplisit mencabut / menolak? Tolak akan menimpa hibah sehingga ada masalah Anda ... Anda harus dapat mencapai ini dengan menambahkan hibah ke tampilan dan tidak melakukan apa pun di atas meja.
Berikut adalah contoh cepat di mana SELECT
belum diberikan secara eksplisit di atas meja, tetapi telah di tampilan. Pengguna dapat memilih dari tampilan tetapi bukan tabel.
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;
Perhatikan bahwa asumsi foo
ini belum diberikan hak tinggi melalui izin eksplisit pada skema atau basis data, atau melalui peran atau keanggotaan grup.
Karena Anda menggunakan tabel dalam beberapa basis data (maaf saya melewatkan akhir kalimat pertama itu pada awalnya), Anda juga mungkin memerlukan hibah eksplisit pada tabel di dalam database di mana tampilan tidak ada. Untuk menghindari pemberian pilih ke tabel, Anda bisa membuat tampilan di setiap database, dan kemudian bergabung dengan tampilan.
Buat dua database dan login:
CREATE DATABASE d1;
GO
CREATE DATABASE d2;
GO
USE [master];
GO
CREATE LOGIN blat WITH PASSWORD = 'x', CHECK_POLICY = OFF;
GO
Dalam database d1
, buat pengguna, lalu buat tabel dan tampilan sederhana terhadap tabel itu. Berikan pilihan kepada pengguna hanya terhadap tampilan:
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
Sekarang, di database kedua, buat pengguna, lalu buat tabel lain dan tampilan yang menggabungkan tabel itu ke tampilan di d1
. Berikan hanya pilih untuk tampilan.
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
Sekarang luncurkan jendela permintaan baru dan ubah kredensial menjadi untuk login blat
( EXECUTE AS
tidak berfungsi di sini). Kemudian jalankan hal berikut dari konteks basis data mana pun, dan itu akan berfungsi dengan baik:
SELECT id FROM d1.dbo.v2;
Ini seharusnya menghasilkan kesalahan Msg 229:
SELECT id FROM d1.dbo.t1;
GO
SELECT id FROM d2.dbo.t2;
Hasil:
Msg 229, Level 14, Negara 5, Baris 1
Izin SELECT ditolak pada objek 't1', basis data 'd1', skema 'dbo'.
Msg 229, Level 14, Negara 5, Jalur 3
Izin SELECT ditolak pada objek 't2', basis data 'd2', skema 'dbo'.