Zum Anzeigen eines Datenbankdiagramms ist eine Berechtigung erforderlich

10

Ich habe kürzlich SSDT für unsere Entwickler eingerichtet. Wir erzwingen Änderungen an unseren Entwicklungsdatenbanken, die über SSDT vorgenommen werden, indem wir die Berechtigungen einschränken, über die jeder Entwickler verfügt, wenn er mit dem Server verbunden ist (db_datareader, db_datawriter). Innerhalb von SSDT veröffentlichen wir unsere Änderungen an der Datenbank mithilfe eines Bereitstellungsskripts, das über eine Anmeldung mit erhöhten Berechtigungen eine Verbindung herstellt.

Meine Frage. Angesichts der Tatsache, dass wir diese Länge gewählt haben, um die Datenbank zu sperren (um die Schemadrift zu stoppen); Gibt es eine Möglichkeit, dass die Entwickler die Diagramme in dieser Datenbank anzeigen können, ohne die Berechtigung db_owner zu haben? Ich weiß, dass jeder Entwickler seine eigenen Diagramme erstellen und anzeigen kann, aber ich möchte, dass sie alle Diagramme anzeigen können, die von vielen verschiedenen Entwicklern erstellt wurden.

Ich denke nicht, dass dies helfen wird, aber wir führen SQL Server 2012 aus

Jede Hilfe wird sehr aufgenommen.

Steve
quelle

Antworten:

16

Aus der Dokumentation :

  • Obwohl jeder Benutzer mit Zugriff auf eine Datenbank ein Diagramm erstellen kann, können nach dem Erstellen des Diagramms nur der Ersteller des Diagramms und ein Mitglied der Rolle db_owner das Diagramm sehen.
  • Das Eigentum an Diagrammen kann nur auf Mitglieder der Rolle db_owner übertragen werden. Dies ist nur möglich, wenn der Vorbesitzer des Diagramms aus der Datenbank entfernt wurde.
  • Wenn der Eigentümer eines Diagramms aus der Datenbank entfernt wurde, bleibt das Diagramm in der Datenbank, bis ein Mitglied der Rolle db_owner versucht, es zu öffnen. Zu diesem Zeitpunkt kann das Mitglied db_owner die Übernahme des Diagramms übernehmen.

Es scheint also, dass Sie es mit niedrigeren Rollen wie nicht schaffen werden db_datareader.

Hinter den Kulissen ruft Management Studio Folgendes auf, um die Liste zu erstellen:

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

Sie können also sehen, dass dies mit der Dokumentation übereinstimmt.

Nun ein paar Workaround-Ideen:

  • In einem Logon - Trigger aktualisiert die principal_idvon allen Diagrammen die aktuelle Login zu sein. Dies bedeutet, dass sie Zugriff auf alle Diagramme haben, bis sich die nächste Person anmeldet. Nicht optimal.
  • Verwenden Sie einen Trigger für die sysdiagramsTabelle selbst (es handelt sich nicht wirklich um eine Systemtabelle). Fügen Sie bei jedem Erstellen oder Aktualisieren eines Diagramms eine Kopie für jeden Principal hinzu / aktualisieren Sie sie (mit angehängtem Benutzernamen). Auch nicht optimal, und Sie könnten den ganzen Tag über Leute haben, die sich gegenseitig die Diagramme überschreiben.

Hier ist eine Idee der zweiten Problemumgehung - alles, was Sie hier wirklich pflegen müssen, ist eine Liste der Datenbankprinzipien, auf die Sie zugreifen möchten, um auf die Diagramme zugreifen zu können (Sie möchten auch etwas zum Bereinigen von gelöschten Diagrammen haben und auch einige regelmäßige Wartungsarbeiten, bei denen Diagramme für gelöschte Principals gelöscht werden):

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

Nach dem Erstellen einiger Diagramme sah eine gekürzte Version von Object Explorer für diese Benutzer folgendermaßen aus:

Geben Sie hier die Bildbeschreibung ein

dboSammeln Sie jetzt eine ganze Reihe von Kopien von Diagrammen, was möglicherweise nicht erforderlich ist, aber Sie möchten wahrscheinlich, dass diese in den meisten Fällen der "Meister" sind.

Aaron Bertrand
quelle
Sehr ausführlich. Ich denke, ich werde Ihren letzten Vorschlag ausprobieren. Vielen Dank
Steve
Für alle, die kürzlich auf SSMS 18 (Vorschau) gestoßen sind, sind Datenbankdiagramme eine veraltete Funktion
LowlyDBA
@ LowlyDBA-Datenbankdiagramme wurden wieder in SSMS 18.1
Jeremy Cook
0

Wie pro BOL wird ein Konto mit Datenbank - Besitzer dbo Rechte erforderlich. Mehr Infos hier .

Der Benutzer, der es erstellt hat, oder ein Mitglied der Rolle db_owner kann also Diagramme öffnen.

Kin Shah
quelle