Nếu bạn muốn người dùng chọn từ chế độ xem, tại sao bạn cấp cho bảng? Bằng cách "thu hồi", bạn có nghĩa là thu hồi / từ chối rõ ràng? Từ chối sẽ ghi đè cấp vì vậy có vấn đề của bạn ... bạn sẽ có thể thực hiện việc này bằng cách thêm cấp cho chế độ xem và không làm bất cứ điều gì theo cách trên bảng.
Đây là một ví dụ nhanh, nơi SELECT
chưa được cấp rõ ràng trên bàn, nhưng đã được xem. Người dùng có thể chọn từ chế độ xem nhưng không phải bảng.
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;
Lưu ý rằng giả định foo
này đã không được cấp đặc quyền nâng cao thông qua các quyền rõ ràng trên lược đồ hoặc cơ sở dữ liệu hoặc thông qua vai trò hoặc thành viên nhóm.
Vì bạn đang sử dụng các bảng trong nhiều cơ sở dữ liệu (xin lỗi, tôi đã bỏ lỡ phần cuối của câu đầu tiên đó), nên bạn cũng có thể cần các khoản trợ cấp rõ ràng trên (các) bảng trong cơ sở dữ liệu nơi chế độ xem không tồn tại. Để tránh cấp quyền chọn cho (các) bảng, bạn có thể tạo chế độ xem trong mỗi cơ sở dữ liệu và sau đó tham gia các chế độ xem.
Tạo hai cơ sở dữ liệu và đăng nhập:
CREATE DATABASE d1;
GO
CREATE DATABASE d2;
GO
USE [master];
GO
CREATE LOGIN blat WITH PASSWORD = 'x', CHECK_POLICY = OFF;
GO
Trong cơ sở dữ liệu d1
, tạo người dùng, sau đó tạo bảng và chế độ xem đơn giản đối với bảng đó. Cấp chọn cho người dùng chỉ chống lại chế độ xem:
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
Bây giờ, trong cơ sở dữ liệu thứ hai, tạo người dùng, sau đó tạo một bảng khác và một khung nhìn nối bảng đó với khung nhìn trong d1
. Cấp chỉ chọn để xem.
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
Bây giờ hãy khởi chạy một cửa sổ truy vấn mới và thay đổi thông tin đăng nhập để đăng nhập blat
( EXECUTE AS
không hoạt động ở đây). Sau đó chạy phần sau từ ngữ cảnh của một trong hai cơ sở dữ liệu và nó sẽ hoạt động tốt:
SELECT id FROM d1.dbo.v2;
Cả hai sẽ mang lại lỗi 229 Msg:
SELECT id FROM d1.dbo.t1;
GO
SELECT id FROM d2.dbo.t2;
Các kết quả:
Msg 229, Cấp 14, Trạng thái 5, Dòng 1
Quyền đã bị từ chối trên đối tượng 't1', cơ sở dữ liệu 'd1', lược đồ 'dbo'.
Msg 229, Cấp 14, Trạng thái 5, Dòng 3
Quyền đã bị từ chối trên đối tượng 't2', cơ sở dữ liệu 'd2', lược đồ 'dbo'.