具有不同所有者的 SQL Server 所有权链跨架构,用于从多个架构中选择视图

Posted

技术标签:

【中文标题】具有不同所有者的 SQL Server 所有权链跨架构,用于从多个架构中选择视图【英文标题】:SQL Server ownership chain cross schema with different owners for view selecting from multiple schemas 【发布时间】:2018-07-02 22:57:35 【问题描述】:

我有 1 个具有多个架构的数据库,其中一些由与默认“dbo”用户不同的用户拥有。

我在这些“dbo”模式之一中有一个视图,该视图从其他“dbo”模式中的 5 个表中选择,然后在“UserA”模式中选择 2 个表。

我想授予用户组访问“dbo”架构中视图的权限,而不是基础表。授予视图权限时,我收到错误消息,提示无法从“UserA”拥有的表中进行选择。可以理解和预期,因为视图(以及因此授予的授权)是针对“dbo”的。那么如何在不直接将它们分配给我的用户组的情况下授予对“UserA”表的访问权限。

有什么建议吗?我试图找出是否有某种方法可以通过“dbo”和“UserA”授予对视图的访问权限,但似乎只有 1 个所有者可以授予选择权限?我还尝试在“dbo”架构中创建“UserA”表的视图,然后授予对这些新的“dbo”视图的权限,但这也不起作用。

【问题讨论】:

您谈论的是“这些 'dbo' 模式之一”,但您只能拥有一个名为 'dbo' 的模式。我假设您的意思是“dbo”用户拥有的模式之一,但您能澄清一下吗?列出架构和所有者会有所帮助 简短的回答应该是肯定的......您应该能够授予任何东西的积极权限,当然,Views 的原因之一是单独访问表。听起来可能是这样...***.com/questions/13032818/… SQL Server : View permission to table的可能重复 @DeanOC 我同意我的用词选择令人困惑。我的意思是我创建了一个视图,它是 dbo 拥有的模式。 Schema|Owner 关系为:dbo|dbo, co|dbo, pm|dbo, ua|UserA @MikeM 我的问题与您所链接的问题相似,但我也没有看到该问题的解决方案。顶部结果建议更改视图所有者,我也无法这样做。 【参考方案1】:

当涉及的所有对象都归同一用户所有时,不需要基础表的权限。这在 SQL Server 中称为所有权链接。

看起来你有不同的用户拥有不同的模式,打破了链条。默认情况下,表由模式的所有者拥有(即继承),但这可以通过在表级别更改所有者来覆盖特殊要求。以下是说明此方法的示例脚本。

使用细粒度的对象所有权而不是继承架构所有者不是例行公事。这对大多数人来说并不直观,并增加了管理负担。

USE tempdb;
GO

CREATE USER UserA WITHOUT LOGIN;
GRANT CREATE TABLE TO UserA;
CREATE USER UserB WITHOUT LOGIN;
GRANT CREATE TABLE TO UserB;
CREATE USER UserC WITHOUT LOGIN;
CREATE ROLE YourUserGroup;
ALTER ROLE YourUserGroup ADD MEMBER UserC;
GO
CREATE SCHEMA UserA AUTHORIZATION UserA;
GO
CREATE SCHEMA UserB AUTHORIZATION UserB;
GO

CREATE TABLE dbo.Table1(ID int NOT NULL CONSTRAINT PK_Table1 PRIMARY KEY);
GO

EXECUTE AS USER = 'UserA';
GO
CREATE TABLE UserA.Table1(ID int NOT NULL CONSTRAINT PK_Table1 PRIMARY KEY);
GO
REVERT;
GO

EXECUTE AS USER = 'UserB';
GO
CREATE TABLE UserB.Table1(ID int NOT NULL CONSTRAINT PK_Table1 PRIMARY KEY);
GO
REVERT;
GO

CREATE VIEW dbo.View1
AS
SELECT
      t1.ID AS dboTable1ID
    , t2.ID AS UserATable1ID
    , t3.ID AS UserBTable1ID
FROM dbo.Table1 AS t1
JOIN UserA.Table1 AS t2 ON t2.ID = t1.ID
JOIN UserB.Table1 AS t3 ON t3.ID = t2.ID;
GO
GRANT SELECT ON dbo.View1 TO YourUserGroup;
GO

EXECUTE AS USER = 'UserC';
GO
--this fails due to broken ownership chain
SELECT * FROM dbo.View1;
GO
REVERT;
GO

--change table owner to common owner
ALTER AUTHORIZATION ON OBJECT::UserA.Table1 TO dbo;
ALTER AUTHORIZATION ON OBJECT::UserB.Table1 TO dbo;
GO

EXECUTE AS USER = 'UserC';
GO
--this now succeeds because all objects involved are owned by dbo
SELECT * FROM dbo.View1;
GO
REVERT;
GO

DROP VIEW dbo.View1;
DROP TABLE dbo.Table1;
DROP TABLE UserA.Table1;
DROP TABLE UserB.Table1;
DROP SCHEMA UserA;
DROP SCHEMA UserB;
DROP USER UserA;
DROP USER UserB;
DROP USER UserC;
GO

【讨论】:

虽然这是一个很好的示例,可以理解所有权和用户访问的工作原理,但我看不出这对我的跨模式视图授权有何帮助? @wh4tshisf4c3,您的问题指出“我想授予用户组访问 'dbo' 模式之一的视图而不是基础表的权限”。此示例代码正是这样做的。我错过了什么? 我已经编辑了那段,希望能更清楚。问题是我的视图从具有两个不同所有者的两个模式中的表中进行选择。在为视图所在的架构授予选择权限时,我收到另一个架构中的表的错误。这是有道理的,但是我怎样才能为那些没有对表本身授予选择权限的其他表授予选择权限? 如果您像我的答案中的示例那样更改表上的授权,是否会出现错误?请注意,这不会授予对表的权限,并且视图会从不同模式中的表中进行选择。只能通过从视图中选择来检索数据。除非我遗漏了什么,否则这似乎就是您想要的。

以上是关于具有不同所有者的 SQL Server 所有权链跨架构,用于从多个架构中选择视图的主要内容,如果未能解决你的问题,请参考以下文章

联合所有在 SQL Server 中的视图性能问题

将遗留数据库(MYSQL)导出到具有不同架构的不同数据库(SQL Server)中

如何删除具有数据库所有者权限的 SQL Server 用户

TSQL / SQL-SERVER:如何在具有主键的快照复制中查找所有表

为啥 COUNT(*) 需要对 SQL Server 上的所有表列具有 SELECT 权限?

还原SQL Server 2005数据库后,将所有用户链接到登录