Por favor, não use a interface do usuário para isso. É uma bagunça confusa.
Parece-me que o que você deseja é criar um usuário em um banco de dados, para um login específico, que tenha apenas permissões para selecionar em uma exibição. Então, já que você já criou o login:
USE your_db;
GO
CREATE USER username FROM LOGIN username;
GO
GRANT SELECT ON dbo.MyViewName TO username;
GO
EDIT aqui é um exemplo de script que levará ao erro que você mencionou.
Primeiro, crie alguma tabela no unrelated_db:
CREATE DATABASE unrelated_db;
GO
USE unrelated_db;
GO
CREATE TABLE dbo.foo(bar INT);
GO
Agora crie um login relativamente restrito:
USE [master];
GO
CREATE LOGIN username WITH PASSWORD='foo', CHECK_POLICY = OFF;
GO
Agora crie um banco de dados no qual a visualização permanecerá e adicione o logon como usuário:
CREATE DATABASE velojason;
GO
USE velojason;
GO
CREATE USER username FROM LOGIN username;
GO
Agora crie uma função que fará referência à tabela no outro banco de dados e um sinônimo para a outra tabela:
CREATE FUNCTION dbo.checkbar()
RETURNS INT
AS
BEGIN
RETURN
(
SELECT TOP (1) bar
FROM unrelated_db.dbo.foo
ORDER BY bar
);
END
GO
CREATE SYNONYM dbo.foo FOR unrelated_db.dbo.foo;
GO
Agora crie uma tabela local:
CREATE TABLE dbo.PaymentDetails
(
PaymentID INT
);
GO
Agora crie uma visualização que faça referência à tabela, à função e ao sinônimo e conceda SELECT
a username
:
CREATE VIEW dbo.SomeView
AS
SELECT
p.PaymentID,
x = dbo.checkbar(), -- function that pulls from other DB
y = (SELECT bar FROM dbo.foo) -- synonym to other DB
FROM dbo.PaymentDetails AS p;
GO
GRANT SELECT ON dbo.SomeView TO username;
GO
Agora tente executar como username
e selecione apenas a coluna local na exibição:
EXECUTE AS USER = 'username';
GO
-- even though I don't reference any of the columns
-- in the other DB, I am denied SELECT on the view:
SELECT PaymentID FROM dbo.SomeView;
GO
REVERT;
GO
Resultado:
Mensagem 916, Nível 14, Estado 1, Linha 3
O principal "nome de usuário" do servidor não pode acessar o banco de dados "unrelated_db" no contexto de segurança atual.
Agora altere a exibição para não fazer referência a objetos externos e execute o acima SELECT
novamente, e ele funciona:
ALTER VIEW dbo.SomeView
AS
SELECT
p.PaymentID
--x = dbo.checkbar(),
--y = (SELECT bar FROM dbo.foo)
FROM dbo.PaymentDetails AS p;
GO
Com exceção de nos mostrar os scripts para os objetos Detalhes do pagamento, Detalhes da conta e MyView, talvez você possa nos informar se essa consulta retorna algum resultado. Você pode encontrar referências a vários objetos através da visualização de catálogo sys.sql_expression_dependencies
, mas essa visualização não é perfeita - acredito que depende de todas as visualizações serem atualizadas (no caso em que visualizações referenciam outras visualizações, por exemplo, ou o esquema subjacente foi alterado) em ordem Para ser exato.
DECLARE
@dbname SYSNAME = N'unrelated_db',
@viewname SYSNAME = N'dbo.SomeView';
SELECT DISTINCT
[This object] =
OBJECT_SCHEMA_NAME([referencing_id])
+ '.' + OBJECT_NAME([referencing_id]),
[references this object] =
OBJECT_SCHEMA_NAME([referenced_id])
+ '.' + OBJECT_NAME([referenced_id]),
[and touches this database] = referenced_database_name,
[and is a(n)] = o.type_desc,
[if synonym, it references] = s.base_object_name
FROM sys.sql_expression_dependencies AS d
LEFT OUTER JOIN sys.objects AS o
ON o.[object_id] = d.referenced_id
LEFT OUTER JOIN sys.synonyms AS s
ON d.referenced_id = s.[object_id]
AND s.base_object_name LIKE '%[' + @dbname + ']%'
WHERE OBJECT_ID(@viewname) IN (
referenced_id,
referencing_id,
(SELECT referencing_id FROM sys.sql_expression_dependencies
WHERE referenced_database_name = @dbname)
) OR referenced_database_name = @dbname;
O SQL Server não está apenas tentando acessar unrelated_db
por diversão ... deve haver algum vínculo com esse banco de dados da exibição que você está tentando usar. Infelizmente, se não conseguimos ver a definição da visualização e mais detalhes sobre os objetos em que ela toca, tudo o que podemos fazer é especular. As duas principais coisas em que consigo pensar são sinônimos ou funções que usam nomes de três partes, mas ver os scripts reais nos dará uma idéia muito melhor do que adivinhar. :-)
Você também pode querer verificar sys.dm_sql_referenced_entities
, no entanto, esta função não retorna nada útil no exemplo acima.