正如我在我的(现已删除的)cmets 中提到的,使用模式可能是这里更简单的解决方案。尽管您可以将USER 权限明确授予CREATE 和VIEW,但ALTER 不能是细粒度的。但是,您可以让他们访问特定模式,然后他们可以创建(和ALTER)他们认为合适的视图。这是一个演示该方法的“快速”示例:
USE master;
GO
CREATE DATABASE TestDB;
GO
USE TestDB;
GO
CREATE TABLE dbo.YourTable (ID int IDENTITY(1,1) CONSTRAINT PK_YourTable PRIMARY KEY,
SomeInt int NOT NULL);
GO
CREATE TABLE dbo.AnotherTable (ID int IDENTITY CONSTRAINT PK_AnotherTable PRIMARY KEY,
YourID int NOT NULL CONSTRAINT FK_AnotherTable_YourID FOREIGN KEY REFERENCES dbo.YourTable(ID),
SomeDate date NULL);
GO
INSERT INTO dbo.YourTable (SomeInt)
VALUES(1),(17),(12),(1634),(-5);
GO
INSERT INTO dbo.AnotherTable (YourID,
SomeDate)
VALUES(1,GETDATE()),(1,'20220101'),
(3,GETDATE()),
(4,'20221001'),(4,'20221002'),(4,'20221003'),
(5,'20221215'),(5,'20221015');
GO
GO
CREATE SCHEMA V; --V for Vende.... View
GO
CREATE USER SomeUser WITHOUT LOGIN;
GO
GRANT ALTER, CONTROL,SELECT ON SCHEMA::V TO SomeUser;
GRANT CREATE VIEW TO SomeUser;
GO
EXECUTE AS USER = 'SomeUser';
GO
--This will fail
CREATE VIEW dbo.NoAccess AS
SELECT ID,
YourID,
SomeDate
FROM dbo.AnotherTable;
GO
SELECT *
FROM dbo.NoAccess;
GO
--This'll work
CREATE VIEW V.RelatedRows AS
SELECT Y.ID AS YourID,
Y.SomeInt,
A.ID AS AnotherID,
A.SomeDate
FROM dbo.YourTable Y
JOIN dbo.AnotherTable A ON Y.ID = A.YourID;
GO
SELECT *
FROM V.RelatedRows;
GO
--Alter the View to a LEFT JOIN
CREATE OR ALTER VIEW V.RelatedRows AS
SELECT Y.ID AS YourID,
Y.SomeInt,
A.ID AS AnotherID,
A.SomeDate
FROM dbo.YourTable Y
LEFT JOIN dbo.AnotherTable A ON Y.ID = A.YourID;
GO
--For this example, they also have no direct access to the tables; you may need to change this.
SELECT *
FROM dbo.YourTable;
GO
REVERT;
GO
USE master;
GO
DROP DATABASE TestDB;
以上将CREATE 和ALTER VIEW V.RelatedRows,同时无法创建VIEW dbo.NoAccess。如前所述,我没有将dbo 架构的显式访问权限授予USER,他们只能通过权限链接访问数据。这可能不是所希望的,但我想证明用户实际上甚至不需要直接访问表就能够在这种情况下使用它。