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 d' ouverture de session, mettez à jour le
principal_id
de tous les diagrammes pour la connexion en cours. 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
sysdiagrams
table elle-même (ce n'est pas vraiment une table système), et chaque fois qu'un diagramme est créé ou mis à jour, ajoutez / mettez à jour une copie pour chaque principal (avec leur nom d'utilisateur en annexe). Pas optimal non plus, et vous pourriez avoir des gens qui écrasent les diagrammes les uns des autres 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.