Permissão necessária para visualizar um diagrama do banco de dados

10

Recentemente, configurei o SSDT para nossos desenvolvedores usarem. Aplicamos alterações em nossos bancos de dados de desenvolvimento por meio do SSDT, limitando as permissões que cada desenvolvedor tem quando conectado ao servidor (db_datareader, db_datawriter). No SSDT, publicamos nossas alterações no banco de dados usando um script de implantação que se conecta usando um logon com permissões elevadas.

Minha pergunta. Dado que fomos até esse ponto para bloquear o banco de dados (para interromper a deriva do esquema); existe alguma maneira de os desenvolvedores poderem visualizar os diagramas nesse banco de dados sem ter que ter permissão db_owner? Eu sei que cada desenvolvedor pode criar e visualizar seus próprios diagramas, mas eu quero que eles possam visualizar todos os diagramas, que foram criados por muitos desenvolvedores diferentes.

Eu não acho que isso vai ajudar, mas estamos executando o sql server 2012

Qualquer ajuda será muito recebida.

Steve
fonte

Respostas:

16

A partir da documentação :

  • Embora qualquer usuário com acesso a um banco de dados possa criar um diagrama, depois que o diagrama for criado, os únicos usuários que poderão vê-lo serão o criador do diagrama e qualquer membro da função db_owner.
  • A propriedade dos diagramas pode ser transferida apenas para membros da função db_owner. Isso só é possível se o proprietário anterior do diagrama tiver sido removido do banco de dados.
  • Se o proprietário de um diagrama tiver sido removido do banco de dados, o diagrama permanecerá no banco de dados até que um membro da função db_owner tente abri-lo. Nesse ponto, o membro db_owner pode optar por assumir a propriedade do diagrama.

Portanto, parece que você não será capaz de fazê-lo com papéis inferiores db_datareader.

Nos bastidores, eis o que o Management Studio está chamando para conduzir a 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

Então você pode ver que isso corresponde à documentação.

Agora, algumas idéias alternativas:

  • Em um gatilho de logon, atualize o principal_idde todos os diagramas para ser o login atual. Isso significa que eles terão acesso a todos os diagramas até que a próxima pessoa faça login. Não é o ideal.
  • Use um gatilho na sysdiagramsprópria tabela (não é realmente uma tabela do sistema) e, sempre que um diagrama for criado ou atualizado, adicione / atualize uma cópia para cada principal (com o nome de usuário anexado). Também não é o ideal, e você pode ter pessoas substituindo os diagramas umas das outras o dia todo.

Aqui está uma idéia da segunda solução alternativa - tudo o que você realmente precisa manter aqui é uma lista dos principais do banco de dados que você deseja acessar os diagramas (você também precisará de algo para limpar os diagramas que foram excluídos e também algumas manutenções periódicas que excluem diagramas de entidades que foram excluídas):

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

Após criar alguns diagramas, eis a aparência de uma versão resumida do Object Explorer para esses usuários:

insira a descrição da imagem aqui

Agora, dbovocê coletará um monte de cópias de diagramas, o que talvez não seja necessário, mas você provavelmente deseja que elas sejam o "mestre" na maioria das circunstâncias.

Aaron Bertrand
fonte
Muito completo. acho que vou tentar sua última sugestão. thanks a lot
Steve
Para quem vem através deste recentemente, a partir de SSMS 18 (Preview) diagramas de banco de dados são um recurso preterido
LowlyDBA
Os diagramas do banco de dados @LowlyDBA foram adicionados novamente ao SSMS 18.1
Jeremy Cook
0

Conforme o BOL , é necessária uma conta com privilégios dbo do proprietário do banco de dados. Mais informações aqui .

Portanto, o usuário que o criou ou um membro da função db_owner pode abrir diagramas.

Kin Shah
fonte