web-dev-qa-db-fra.com

Autorisation requise pour afficher un diagramme de base de données

J'ai récemment mis en place SSDT pour nos développeurs. Nous appliquons les modifications à nos bases de données de développement via SSDT en limitant les autorisations dont chaque développeur dispose lorsqu'il est connecté au serveur (db_datareader, db_datawriter). Dans SSDT, nous publions nos modifications dans la base de données à l'aide d'un script de déploiement qui se connecte à l'aide d'une connexion avec des autorisations élevées.

Ma question. Étant donné que nous sommes allés à cette longueur pour verrouiller la base de données (pour arrêter la dérive du schéma); existe-t-il un moyen pour les développeurs de visualiser les diagrammes sur cette base de données sans avoir à avoir l'autorisation db_owner? Je sais que chaque développeur peut créer et afficher ses propres diagrammes, mais je veux qu'ils puissent voir tous les diagrammes, qui ont été créés par de nombreux développeurs différents.

Je ne pense pas que cela aidera, mais nous exécutons SQL Server 2012

Toute aide sera grandement reçue.

10
Steve

De la documentation :

  • Bien que tout utilisateur ayant accès à une base de données puisse créer un diagramme, une fois le diagramme créé, les seuls utilisateurs qui peuvent le voir sont le créateur du diagramme et tout membre du rôle db_owner.
  • La propriété des diagrammes ne peut être transférée qu'aux membres du rôle db_owner. Cela n'est possible que si l'ancien propriétaire du diagramme a été supprimé de la base de données.
  • Si le propriétaire d'un diagramme a été supprimé de la base de données, le diagramme restera dans la base de données jusqu'à ce qu'un membre du rôle db_owner tente de l'ouvrir. À ce stade, le membre db_owner peut choisir de reprendre la propriété du diagramme.

Il semble donc que vous ne pourrez pas le faire avec des rôles inférieurs comme db_datareader.

Dans les coulisses, voici ce que Management Studio appelle pour conduire la liste:

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

Vous pouvez donc voir que cela correspond à la documentation.

Maintenant quelques idées de contournement:

  • Dans un déclencheur de connexion, mettez à jour le principal_id de tous les diagrammes pour être la connexion actuelle. Cela signifie qu'ils auront accès à tous les diagrammes jusqu'à ce que la prochaine personne se connecte. Pas optimal.
  • Utilisez un déclencheur sur la table sysdiagrams elle-même (ce n'est pas vraiment une table système), et chaque fois qu'un diagramme est créé ou mis à jour, ajoutez/mettre à jour une copie pour chaque principal (avec leur nom d'utilisateur en annexe). Pas optimal non plus, et vous pourriez avoir des gens qui se remplacent mutuellement les diagrammes toute la journée.

Voici une idée de la deuxième solution de contournement - tout ce que vous avez vraiment à maintenir ici est une liste des principaux de base de données que vous souhaitez pouvoir accéder aux diagrammes (vous voudrez également avoir quelque chose à nettoyer les diagrammes qui ont été supprimés , ainsi qu'une maintenance périodique qui supprime les diagrammes des principaux qui ont été supprimés):

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

Après avoir créé quelques diagrammes, voici à quoi ressemblait une version abrégée de l'Explorateur d'objets pour ces utilisateurs:

enter image description here

Maintenant, dbo va collecter un tas de copies de diagrammes, ce qui n'est peut-être pas nécessaire, mais vous voulez probablement que ce soit le "maître" dans la plupart des circonstances.

16
Aaron Bertrand

Selon BOL , un compte avec les privilèges dbo du propriétaire de la base de données est requis. Plus d'infos ici .

Ainsi, l'utilisateur qui l'a créé ou un membre du rôle db_owner peut ouvrir des diagrammes.

0
Kin Shah