Kullanıcıların görünümden seçim yapmasını istiyorsanız, neden tabloya veriyorsunuz? "İptal" demekle açıkça iptal / reddetmek mi? Reddet, hibe geçersiz kılar, böylece sorununuz var ... bunu , görünüme hibe ekleyerek ve tablolarda herhangi bir şekilde bir şey yapmadan yapabilmeniz gerekir .
İşte SELECT
açık bir şekilde masaya verilmemiş ancak görünümde olan hızlı bir örnek . Kullanıcı tablodan değil görünümden seçim yapabilir.
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;
Bu varsayımın foo
şema veya veritabanındaki açık izinlerle veya rol veya grup üyeliği yoluyla yükseltilmiş ayrıcalıklar verilmediğini unutmayın .
Birden çok veritabanında tablolar kullandığınız için (üzgünüm başlangıçta bu ilk cümlenin sonunu kaçırdım), ayrıca görünümün bulunmadığı veritabanındaki tablolarda açık hibelere de ihtiyacınız olabilir. Tablolara seçim vermekten kaçınmak için, her veritabanında bir görünüm oluşturabilir ve sonra görünümlere katılabilirsiniz.
İki veritabanı ve bir giriş oluşturun:
CREATE DATABASE d1;
GO
CREATE DATABASE d2;
GO
USE [master];
GO
CREATE LOGIN blat WITH PASSWORD = 'x', CHECK_POLICY = OFF;
GO
Veritabanında d1
bir kullanıcı oluşturun, ardından bir tablo ve o tabloya karşı basit bir görünüm oluşturun. Kullanıcıya yalnızca görünüme karşı seçim izni verin :
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
Şimdi, ikinci veritabanında, kullanıcıyı oluşturun, sonra başka bir tablo ve bu tabloyu görünüme birleştiren bir görünüm oluşturun d1
. Yalnızca görünüme seçme izni verme.
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
Şimdi yeni bir sorgu penceresi başlatın ve oturum açma için kimlik bilgilerini değiştirin blat
( EXECUTE AS
burada çalışmaz). Sonra her iki veritabanı bağlamında aşağıdakileri çalıştırın ve iyi çalışması gerekir:
SELECT id FROM d1.dbo.v2;
Bunların her ikisi de Msg 229 hataları vermelidir:
SELECT id FROM d1.dbo.t1;
GO
SELECT id FROM d2.dbo.t2;
Sonuçlar:
Msg 229, Seviye 14, Durum 5, Satır 1
't1' nesnesi, 'd1' veritabanı, 'dbo' şeması üzerinde SELECT izni reddedildi.
Msg 229, Seviye 14, Durum 5, Satır 3
't2' nesnesi, 'd2' veritabanı, 'dbo' şeması üzerinde SELECT izni reddedildi.