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.
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:
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.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:
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.