Se requiere permiso para ver un diagrama de base de datos

10

Recientemente he configurado SSDT para que lo usen nuestros desarrolladores. Aplicamos cambios a nuestras bases de datos de desarrollo a través de SSDT limitando los permisos que cada desarrollador tiene cuando está conectado al servidor (db_datareader, db_datawriter). Dentro de SSDT publicamos nuestros cambios en la base de datos utilizando un script de implementación que se conecta mediante un inicio de sesión con permisos elevados.

Mi pregunta. Dado que hemos llegado a esta longitud para bloquear la base de datos (para detener la deriva del esquema); ¿Hay alguna manera de que los desarrolladores puedan ver los diagramas en esta base de datos sin tener que tener el permiso db_owner? Sé que cada desarrollador puede crear y ver sus propios diagramas, pero quiero que puedan ver todos los diagramas, que han sido creados por muchos desarrolladores diferentes.

No creo que esto ayude, pero estamos ejecutando SQL Server 2012

Cualquier ayuda será muy recibida.

Steve
fuente

Respuestas:

16

De la documentación :

  • Aunque cualquier usuario con acceso a una base de datos puede crear un diagrama, una vez que se ha creado el diagrama, los únicos usuarios que pueden verlo son el creador del diagrama y cualquier miembro de la función db_owner.
  • La propiedad de los diagramas solo se puede transferir a los miembros de la función db_owner. Esto solo es posible si el propietario anterior del diagrama ha sido eliminado de la base de datos.
  • Si el propietario de un diagrama ha sido 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 elegir hacerse cargo de la propiedad del diagrama.

Por lo tanto, parece que no podrá hacerlo con roles más bajos 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

Para que pueda ver esto coincide con la documentación.

Ahora un par de ideas alternativas:

  • En un inicio de sesión de inicio de sesión, actualice el principal_idde todos los diagramas para que sea 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.
  • Use un activador en la sysdiagramstabla en sí (no es realmente una tabla del sistema), y cada vez que se crea o actualiza un diagrama, agregue / actualice una copia para cada entidad de seguridad (con su nombre de usuario adjunto). Tampoco es óptimo, y podría hacer que las personas se sobrescriban 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 principios de la base de datos a los 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 de los principales que se han eliminado):

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 una versión resumida de Object Explorer para estos usuarios:

ingrese la descripción de la imagen aquí

Ahora, dborecopilará 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.

Aaron Bertrand
fuente
Muy minucioso. Creo que intentaré tu última sugerencia. muchas gracias
Steve
Para cualquiera que se encuentre con esto recientemente, a partir de SSMS 18 (vista previa), los diagramas de la base de datos son una característica obsoleta
LowlyDBA
Los diagramas de base de datos de @LowlyDBA se agregaron nuevamente a SSMS 18.1
Jeremy Cook el
0

Según BOL , se requiere una cuenta con privilegios dbo de propietario de la base de datos. Más información aquí .

Por lo tanto, el usuario que lo creó o un miembro de la función db_owner puede abrir diagramas.

Kin Shah
fuente