Solución:
De la documentación:
- Aunque cualquier usuario con acceso a una base de datos puede crear un diagrama, una vez creado el diagrama, los únicos usuarios que pueden verlo son el creador del diagrama y cualquier miembro del rol db_owner.
- La propiedad de los diagramas solo se puede transferir a miembros del rol db_owner. Esto solo es posible si el propietario anterior del diagrama se ha eliminado de la base de datos.
- Si el propietario de un diagrama se ha eliminado de la base de datos, el diagrama permanecerá en la base de datos hasta que un miembro del rol db_owner intente abrirlo. En ese momento, el miembro db_owner puede optar por hacerse cargo del diagrama.
Entonces parece que no podrás hacerlo con roles inferiores como db_datareader
.
Detrás de escena, esto es lo que Management Studio está llamando para impulsar la lista:
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
Entonces puede ver que esto coincide con la documentación.
Ahora un par de ideas alternativas:
- En un desencadenador de inicio de sesión, actualice el
principal_id
de todos diagramas para ser el inicio de sesión actual. Esto significa que tendrán acceso a todos los diagramas hasta que la siguiente persona inicie sesión. No es óptimo. - Utilice un gatillo en el
sysdiagrams
mesa en sí (no es De Verdad una tabla del sistema), y cada vez que se crea o actualiza un diagrama, agregue / actualice una copia para cada principal (con su nombre de usuario adjunto). Tampoco es óptimo, y podría tener personas sobrescribiendo los diagramas de los demás durante todo el día.
Aquí hay una idea de la segunda solución: todo lo que realmente tiene que mantener aquí es una lista de los principales de la base de datos que desea poder acceder a los diagramas (también querrá tener algo para limpiar los diagramas que se han eliminado , y también un mantenimiento periódico que elimina los diagramas para directores que han sido eliminados):
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
Después de crear un par de diagramas, así es como se veía una versión abreviada de Object Explorer para estos usuarios:
Ahora, dbo
recopilará un montón de copias de diagramas, lo que tal vez no sea necesario, pero probablemente desee que sean el “maestro” en la mayoría de las circunstancias.