これにはUIを使用しないでください。紛らわしい混乱です。
特定のログインに対して、1つのビューから選択する権限のみを持つユーザーをデータベースに作成したいようです。そのため、すでにログインが作成されているため:
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
次に、asを実行して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
サーバープリンシパル "username"は、現在のセキュリティコンテキストでデータベース "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
Payment Details、Account Details、および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
面白さのためにアクセスしようとするだけではありません...使用しようとしているビューからそのデータベースに何らかの結び付けがなければなりません。残念ながら、ビューの定義と、それが触れるオブジェクトの詳細が表示されない場合は、推測するだけです。私が考えることができる2つの主なものは、3部構成の名前を使用する同義語または関数ですが、実際のスクリプトを見ると、推測するよりもはるかに良いアイデアが得られます。:-)
をチェックすることもできますがsys.dm_sql_referenced_entities
、この関数は上記の例では有用なものを何も返しません。