SQL 服务器 - 授予用户在他们自己的架构中创建 table 的权限,但不能在 dbo 架构中创建
SQL Server - Give user permission to create table in their own schema, but not in dbo schema
我不是 DBA,但被要求帮助为一些内部公司建立教学数据库 SQL 类。我正在使用 Azure SQL 服务器数据库,其中每个学生都需要能够为自己创建 tables、视图和存储过程,但不能看到任何其他学生的工作。由于成本限制,我无法为每个学生创建一个 Azure 数据库并用原始数据加载它,所以我试图在一个数据库中完成这一切。
这是我的想法:
- 为每个学生创建一个架构并授予他们写入权限
- 授予他们从 dbo 架构中读取的权限
原始数据将被存储,但不会写入(我不想给他们机会覆盖原始 tables)。
- 隐藏所有其他学生的架构,以便学生只能看到他们的
tables/views/sprocs 和 dbo 架构中的那些。
我已经能够创建登录名、用户和模式,并授予对 dbo 模式的读取权限,但我无法让学生完全控制他们自己的模式。
我需要的建议是,我如何设置数据库让每个学生都有自己的模式和写访问权限,但对 dbo 模式有只读访问权限?似乎我可以锁定学生模式,但不能在没有对整个数据库的写访问权限的情况下授予他们对它的写访问权限。有没有办法把它们分开?
此外,关于在同一数据库中分离学生的环境,是否有更好的方法来实现我想要的效果?
这是我目前尝试过的方法:
USE MASTER
CREATE LOGIN student1 WITH PASSWORD = 'T3mpSuperSecret!';
USE class_DB
CREATE USER student1 FOR LOGIN student1;
CREATE SCHEMA st1 AUTHORIZATION student1;
GRANT SELECT ON SCHEMA :: dbo TO student1
GRANT CONTROL ON SCHEMA :: st1 TO student1
然后我尝试 select 来自 dbo 的基础 table 之一进入新模式:
select *
into st1.inventories
from dbo.inventories
我得到:
Msg 262, Level 14, State 1, Line 1
CREATE TABLE permission denied in database 'class_DB'.
看起来创建 table 权限是在数据库级别,而不是模式级别。有没有办法在架构级别授权创建 table 权限?
我希望这一切都有意义。同样,我不是 DBA,所以任何帮助将不胜感激。
谢谢!
授予 CREATE TABLE
和其他权限没有任何作用是 USER
也没有 ALTER
权限。因此,您只需要 GRANT
USER
CREATE TABLE
、CREATE VIEW
等对其特定模式的权限,然后 SELECT
dbo
架构。
这与 WITHOUT LOGIN
一起使用作为示例,因为我没有 LOGIN
对象,但这表明已授予并隐式拒绝了权限:
CREATE DATABASE SampleDB;
GO
USE SampleDB;
GO
CREATE TABLE dbo.SomeTable (SomeID int IDENTITY);
INSERT INTO dbo.SomeTable
DEFAULT VALUES;
GO
CREATE USER student1 WITHOUT LOGIN;
GO
CREATE SCHEMA st1 AUTHORIZATION student1;
GO
GRANT SELECT ON SCHEMA::dbo TO student1;
GRANT CREATE TABLE, CREATE VIEW, CREATE FUNCTION, CREATE PROCEDURE TO student1;
GO
CREATE USER student2 WITHOUT LOGIN;
GO
CREATE SCHEMA st2 AUTHORIZATION student2;
GO
GRANT SELECT ON SCHEMA::dbo TO student2;
GRANT CREATE TABLE, CREATE VIEW, CREATE FUNCTION, CREATE PROCEDURE TO student2;
GO
EXECUTE AS USER = 'student1';
GO
CREATE TABLE st1.TestTable (ID int);
INSERT INTO st1.TestTable
SELECT SomeID
FROM dbo.SomeTable;
GO
SELECT *
FROM st1.TestTable;
GO
REVERT;
GO
EXECUTE AS USER = 'student2';
GO
CREATE PROC st2.TestProc AS
BEGIN
SELECT *
FROM st1.TestTable;
END;
GO
EXEC st2.TestProc; --fails
GO
CREATE TABLE st1.TestTable (ID int); --fails too
GO
REVERT;
GO
USE master;
GO
DROP DATABASE SampleDB;
我不是 DBA,但被要求帮助为一些内部公司建立教学数据库 SQL 类。我正在使用 Azure SQL 服务器数据库,其中每个学生都需要能够为自己创建 tables、视图和存储过程,但不能看到任何其他学生的工作。由于成本限制,我无法为每个学生创建一个 Azure 数据库并用原始数据加载它,所以我试图在一个数据库中完成这一切。
这是我的想法:
- 为每个学生创建一个架构并授予他们写入权限
- 授予他们从 dbo 架构中读取的权限 原始数据将被存储,但不会写入(我不想给他们机会覆盖原始 tables)。
- 隐藏所有其他学生的架构,以便学生只能看到他们的 tables/views/sprocs 和 dbo 架构中的那些。
我已经能够创建登录名、用户和模式,并授予对 dbo 模式的读取权限,但我无法让学生完全控制他们自己的模式。
我需要的建议是,我如何设置数据库让每个学生都有自己的模式和写访问权限,但对 dbo 模式有只读访问权限?似乎我可以锁定学生模式,但不能在没有对整个数据库的写访问权限的情况下授予他们对它的写访问权限。有没有办法把它们分开?
此外,关于在同一数据库中分离学生的环境,是否有更好的方法来实现我想要的效果?
这是我目前尝试过的方法:
USE MASTER
CREATE LOGIN student1 WITH PASSWORD = 'T3mpSuperSecret!';
USE class_DB
CREATE USER student1 FOR LOGIN student1;
CREATE SCHEMA st1 AUTHORIZATION student1;
GRANT SELECT ON SCHEMA :: dbo TO student1
GRANT CONTROL ON SCHEMA :: st1 TO student1
然后我尝试 select 来自 dbo 的基础 table 之一进入新模式:
select *
into st1.inventories
from dbo.inventories
我得到:
Msg 262, Level 14, State 1, Line 1
CREATE TABLE permission denied in database 'class_DB'.
看起来创建 table 权限是在数据库级别,而不是模式级别。有没有办法在架构级别授权创建 table 权限?
我希望这一切都有意义。同样,我不是 DBA,所以任何帮助将不胜感激。
谢谢!
授予 CREATE TABLE
和其他权限没有任何作用是 USER
也没有 ALTER
权限。因此,您只需要 GRANT
USER
CREATE TABLE
、CREATE VIEW
等对其特定模式的权限,然后 SELECT
dbo
架构。
这与 WITHOUT LOGIN
一起使用作为示例,因为我没有 LOGIN
对象,但这表明已授予并隐式拒绝了权限:
CREATE DATABASE SampleDB;
GO
USE SampleDB;
GO
CREATE TABLE dbo.SomeTable (SomeID int IDENTITY);
INSERT INTO dbo.SomeTable
DEFAULT VALUES;
GO
CREATE USER student1 WITHOUT LOGIN;
GO
CREATE SCHEMA st1 AUTHORIZATION student1;
GO
GRANT SELECT ON SCHEMA::dbo TO student1;
GRANT CREATE TABLE, CREATE VIEW, CREATE FUNCTION, CREATE PROCEDURE TO student1;
GO
CREATE USER student2 WITHOUT LOGIN;
GO
CREATE SCHEMA st2 AUTHORIZATION student2;
GO
GRANT SELECT ON SCHEMA::dbo TO student2;
GRANT CREATE TABLE, CREATE VIEW, CREATE FUNCTION, CREATE PROCEDURE TO student2;
GO
EXECUTE AS USER = 'student1';
GO
CREATE TABLE st1.TestTable (ID int);
INSERT INTO st1.TestTable
SELECT SomeID
FROM dbo.SomeTable;
GO
SELECT *
FROM st1.TestTable;
GO
REVERT;
GO
EXECUTE AS USER = 'student2';
GO
CREATE PROC st2.TestProc AS
BEGIN
SELECT *
FROM st1.TestTable;
END;
GO
EXEC st2.TestProc; --fails
GO
CREATE TABLE st1.TestTable (ID int); --fails too
GO
REVERT;
GO
USE master;
GO
DROP DATABASE SampleDB;