Se desideri che gli utenti selezionino dalla vista, perché concedi alla tabella? Con "revoca" intendi esplicitamente revocare / negare? Nega sovrascriverà la concessione, quindi c'è il tuo problema ... dovresti essere in grado di farlo aggiungendo la sovvenzione alla vista e non facendo nulla in alcun modo sui tavoli.
Ecco un breve esempio in cui SELECT
non è stato concesso esplicitamente sulla tabella, ma è stato visualizzato. L'utente può selezionare dalla vista ma non dalla tabella.
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;
Si noti che ciò presuppone che foo
non siano stati concessi privilegi elevati tramite autorizzazioni esplicite sullo schema o sul database o tramite l'appartenenza a ruoli o gruppi.
Dato che stai utilizzando le tabelle in più database (mi dispiace, all'inizio, ho perso la fine della prima frase), potresti anche aver bisogno di sovvenzioni esplicite sulle tabelle nel database in cui la vista non esiste. Per evitare di concedere la selezione alle tabelle, è possibile creare una vista in ciascun database e quindi unire le viste.
Crea due database e un login:
CREATE DATABASE d1;
GO
CREATE DATABASE d2;
GO
USE [master];
GO
CREATE LOGIN blat WITH PASSWORD = 'x', CHECK_POLICY = OFF;
GO
Nel database d1
, creare un utente, quindi creare una tabella e una vista semplice rispetto a quella tabella. Concedi la selezione all'utente solo per la vista:
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
Ora, nel secondo database, creare l'utente, quindi creare un'altra tabella e una vista che unisce quella tabella alla vista in d1
. Concedi selezionare solo per la vista.
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
Ora avvia una nuova finestra di query e modifica le credenziali per l'accesso blat
( EXECUTE AS
non funziona qui). Quindi eseguire quanto segue dal contesto di entrambi i database e dovrebbe funzionare correttamente:
SELECT id FROM d1.dbo.v2;
Questi dovrebbero entrambi generare errori 229:
SELECT id FROM d1.dbo.t1;
GO
SELECT id FROM d2.dbo.t2;
risultati:
Messaggio 229, livello 14, stato 5, riga 1
L'autorizzazione SELECT è stata negata sull'oggetto 't1', database 'd1', schema 'dbo'.
Messaggio 229, livello 14, stato 5, riga 3
L'autorizzazione SELECT è stata negata sull'oggetto 't2', database 'd2', schema 'dbo'.