이를 위해 UI를 사용하지 마십시오. 혼란스러운 혼란입니다.
하나의보기에서 선택할 권한이있는 특정 로그인에 대해 데이터베이스에 사용자를 만드는 것이 원하는 것처럼 들립니다. 따라서 이미 로그인이 생성되었으므로
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
지불 세부 사항, 계정 세부 사항 및 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
있지만,이 함수는 위 예제에서 유용한 것을 반환하지 않습니다.