查看数据库图所需的权限


10

我最近设置了SSDT供我们的开发人员使用。通过限制每个开发人员连接到服务器(db_datareader,db_datawriter)时的权限,我们通过SSDT强制对开发数据库进行更改。在SSDT中,我们使用部署脚本将更改发布到数据库,该脚本使用具有提升权限的登录名进行连接。

我的问题。鉴于我们已经竭尽全力来锁定数据库(以防止模式漂移);开发人员是否可以通过任何方式查看此数据库上的图表而无需db_owner权限?我知道每个开发人员都可以创建和查看自己的图,但是我希望他们能够查看由许多不同的开发人员创建的所有图。

我认为这不会有所帮助,但我们正在运行sql server 2012

任何帮助都会得到很大的帮助。

Answers:


16

文档中

  • 尽管有权访问数据库的任何用户都可以创建图,但是一旦创建了图,唯一可以看到该图的用户就是图的创建者和db_owner角色的任何成员。
  • 图的所有权只能转让给db_owner角色的成员。仅当该图的先前所有者已从数据库中删除时,才有可能。
  • 如果已将图的所有者从数据库中删除,则该图将保留在数据库中,直到db_owner角色的成员尝试打开它为止。那时,db_owner成员可以选择接管该图的所有权。

因此,您似乎无法使用较低的角色来做到这一点db_datareader

在幕后,这是Management Studio调用以驱动列表的内容:

CREATE PROCEDURE dbo.sp_helpdiagrams
(
    @diagramname sysname = NULL,
    @owner_id int = NULL
)
WITH EXECUTE AS N'dbo'
AS
BEGIN
    DECLARE @user sysname
    DECLARE @dboLogin bit
    EXECUTE AS CALLER;
        SET @user = USER_NAME();
        SET @dboLogin = CONVERT(bit,IS_MEMBER('db_owner'));
    REVERT;
    SELECT
        [Database] = DB_NAME(),
        [Name] = name,
        [ID] = diagram_id,
        [Owner] = USER_NAME(principal_id),
        [OwnerID] = principal_id
    FROM
        sysdiagrams
    WHERE
        (@dboLogin = 1 OR USER_NAME(principal_id) = @user) AND
        (@diagramname IS NULL OR name = @diagramname) AND
        (@owner_id IS NULL OR principal_id = @owner_id)
    ORDER BY
        4, 5, 1
END

因此,您可以看到与此匹配的文档。

现在有两个解决方法:

  • 在登录触发器,更新principal_id所有图表是当前登录。这意味着在下一个用户登录之前,他们将有权访问所有图表。这不是最佳选择。
  • 使用触发器在sysdiagrams表本身(它不是真正的系统表),并且每当创建或更新图表,添加/更新每个主副本(标有自己的用户名)。两者都不是最佳选择,您可能会让人们整天覆盖彼此的图表。

这是第二种解决方法的想法-您真正需要维护的是想要访问图的数据库主体的列表(您还希望有一些清理已删除图的内容) ,以及一些定期维护,这些维护会删除已删除的主体的图):

CREATE TRIGGER dbo.sysdiagrams_distribute
ON dbo.sysdiagrams
WITH EXECUTE AS N'dbo'
FOR INSERT, UPDATE
AS
BEGIN
  SET NOCOUNT ON;

  DECLARE @p TABLE(principal_id INT, name SYSNAME);

  INSERT @p SELECT principal_id, name
    FROM sys.database_principals
    -- change this list:
    WHERE name IN (N'test_blat_user', N'test_blat_user2', N'dbo');

  UPDATE d 
    SET [version] = i.version, definition = i.definition
  FROM inserted AS i
  CROSS JOIN @p AS p
  INNER JOIN dbo.sysdiagrams AS d
  ON d.name = i.name
  AND d.principal_id = p.principal_id;

  INSERT dbo.sysdiagrams(name, principal_id, version, definition)
    SELECT i.name, p.principal_id, i.version, i.definition
    FROM inserted AS i
    CROSS JOIN @p AS p
    WHERE NOT EXISTS 
    (
      SELECT 1 FROM dbo.sysdiagrams WHERE name = i.name
      AND principal_id = p.principal_id
    );
END
GO

在创建了几个图表之后,以下是这些用户的简化版本的Object Explorer:

在此处输入图片说明

现在,dbo将收集一堆图的副本,这也许不是必需的,但是您可能希望在大多数情况下将它们作为“主”。


很彻底 我想我会给你最后的建议。非常感谢
Steve

对于最近遇到这种情况的任何人,从SSMS 18(预览版)开始,数据库图表都是不推荐使用的功能
LowlyDBA

@LowlyDBA数据库图被添加回SSMS 18.1
Jeremy Cook

0

根据BOL,需要具有数据库所有者dbo特权的帐户。更多信息在这里

因此,创建它的用户或db_owner角色的成员可以打开图。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.