Se você deseja que os usuários selecionem a partir da visualização, por que você está concedendo à tabela? Por "revogar", você quer dizer revogar / negar explicitamente? Negar substituirá a concessão, portanto, o problema é seu ... você deve conseguir isso adicionando concessão à exibição e não fazendo nada nas tabelas.
Aqui está um exemplo rápido em SELECT
que não foi concedido explicitamente na tabela, mas foi exibido. O usuário pode selecionar na visualização, mas não na tabela.
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;
Observe que isso pressupõe foo
que não foram concedidos privilégios elevados por meio de permissões explícitas no esquema ou banco de dados, ou por meio de associação de função ou grupo.
Como você está usando tabelas em vários bancos de dados (desculpe, eu perdi o final da primeira frase inicialmente), você também pode precisar de concessões explícitas nas tabelas no banco de dados em que a exibição não existe. Para evitar conceder seleção às tabelas, você pode criar uma visualização em cada banco de dados e depois ingressar nas visualizações.
Crie dois bancos de dados e um logon:
CREATE DATABASE d1;
GO
CREATE DATABASE d2;
GO
USE [master];
GO
CREATE LOGIN blat WITH PASSWORD = 'x', CHECK_POLICY = OFF;
GO
No banco de dados d1
, crie um usuário e crie uma tabela e uma visualização simples nessa tabela. Conceda a seleção ao usuário apenas na visualização:
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
Agora, no segundo banco de dados, crie o usuário e crie outra tabela e uma exibição que une essa tabela à exibição d1
. Conceda a seleção apenas para a visualização.
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
Agora inicie uma nova janela de consulta e altere as credenciais para o logon blat
( EXECUTE AS
não funciona aqui). Em seguida, execute o seguinte no contexto de qualquer banco de dados e deve funcionar bem:
SELECT id FROM d1.dbo.v2;
Ambos devem gerar erros de mensagem 229:
SELECT id FROM d1.dbo.t1;
GO
SELECT id FROM d2.dbo.t2;
Resultados:
Msg 229, Nível 14, Estado 5, Linha 1
A permissão SELECT foi negada no objeto 't1', banco de dados 'd1', esquema 'dbo'.
Msg 229, Nível 14, Estado 5, Linha 3
A permissão SELECT foi negada no objeto 't2', banco de dados 'd2', esquema 'dbo'.