Пожалуйста, не используйте пользовательский интерфейс для этого. Это запутанный беспорядок.
Для меня это звучит так, как будто вы хотите создать пользователя в базе данных для конкретного входа в систему, у которого есть только права на выбор из одного представления. Итак, поскольку вы уже создали логин:
USE your_db;
GO
CREATE USER username FROM LOGIN username;
GO
GRANT SELECT ON dbo.MyViewName TO username;
GO
РЕДАКТИРОВАТЬ здесь пример скрипта, который приведет к указанной вами ошибке.
Сначала создайте таблицу в unrelated_db:
CREATE DATABASE unrelated_db;
GO
USE unrelated_db;
GO
CREATE TABLE dbo.foo(bar INT);
GO
Теперь создайте относительно ограниченный логин:
USE [master];
GO
CREATE LOGIN username WITH PASSWORD='foo', CHECK_POLICY = OFF;
GO
Теперь создайте базу данных, в которой будет жить представление, и добавьте имя пользователя как пользователя:
CREATE DATABASE velojason;
GO
USE velojason;
GO
CREATE USER username FROM LOGIN username;
GO
Теперь создайте функцию, которая будет ссылаться на таблицу в другой базе данных и синоним другой таблицы:
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
Теперь создайте локальную таблицу:
CREATE TABLE dbo.PaymentDetails
(
PaymentID INT
);
GO
Теперь создать представление , которое ссылается на таблицу, то функция и синоним, и грант SELECT
на 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
Теперь попробуйте выполнить как username
и выберите только локальный столбец из представления:
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
Результат:
Сообщение 916, уровень 14, состояние 1, строка 3
Главный пользователь сервера «имя пользователя» не может получить доступ к базе данных «unrelated_db» в текущем контексте безопасности.
Теперь измените представление, чтобы не ссылаться на какие-либо внешние объекты, и SELECT
снова запустите выше , и это работает:
ALTER VIEW dbo.SomeView
AS
SELECT
p.PaymentID
--x = dbo.checkbar(),
--y = (SELECT bar FROM dbo.foo)
FROM dbo.PaymentDetails AS p;
GO
Если не считать сценариев для объектов «Платежная информация», «Сведения о счете» и «MyView», возможно, вы можете сообщить нам, если этот запрос даст какие-либо результаты. Вы можете найти ссылки на различные объекты в представлении каталога sys.sql_expression_dependencies
, но это представление не является идеальным - я полагаю, что оно зависит от всех обновляемых представлений (в случае, когда представления ссылаются, например, на другие представления или базовая схема изменилась) в порядке быть точным
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;
SQL Server не просто попытается получить к нему доступ unrelated_db
для удовольствия ... должна быть некоторая связь с этой базой данных из представления, которое вы пытаетесь использовать. К сожалению, если мы не можем увидеть определение вида и больше деталей об объектах, к которым он прикасается, все, что мы можем сделать, - это спекулировать. Две основные вещи, которые я могу придумать, - это синонимы или функции, которые используют имена из трех частей, но просмотр реальных сценариев даст нам гораздо лучшую идею, чем угадывание. :-)
Вы также можете захотеть проверить sys.dm_sql_referenced_entities
, однако эта функция не возвращает ничего полезного в примере выше.