ドキュメントから:
- データベースへのアクセス権を持つすべてのユーザーがダイアグラムを作成できますが、ダイアグラムが作成されると、それを表示できるのは、ダイアグラムの作成者とdb_ownerロールのメンバーのみです。
- ダイアグラムの所有権は、db_ownerロールのメンバーにのみ転送できます。これは、ダイアグラムの以前の所有者がデータベースから削除されている場合にのみ可能です。
- ダイアグラムの所有者がデータベースから削除されている場合、db_ownerロールのメンバーがそれを開こうとするまで、ダイアグラムはデータベースに残ります。その時点で、db_ownerメンバーは、ダイアグラムの所有権を引き継ぐことを選択できます。
したがって、のような低い役割ではそれを実行できないようdb_datareader
です。
舞台裏で、これはManagement Studioがリストを推進するために呼び出しているものです:
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
これがドキュメントと一致していることがわかります。
いくつかの回避策のアイデア:
- ログオントリガでは、更新
principal_id
のすべての現在のログインであることを図を。つまり、次のユーザーがログインするまで、すべての図にアクセスできます。最適ではありません。
sysdiagrams
テーブル自体(実際にはシステムテーブルではない)でトリガーを使用し、ダイアグラムが作成または更新されるたびに、プリンシパルごとに(ユーザー名を追加して)コピーを追加/更新します。どちらも最適ではなく、1日中人々がお互いの図を上書きする可能性があります。
ここに2番目の回避策のアイデアがあります-ここで実際に維持する必要があるのは、ダイアグラムにアクセスできるようにするデータベースプリンシパルのリストだけです(削除されたダイアグラムをクリーンアップするための何かも必要になるでしょう) 、また、削除されたプリンシパルの図を削除する定期的なメンテナンス):
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
いくつかの図を作成した後、これらのユーザーのオブジェクトエクスプローラーの要約版は次のようになります。
これで、dbo
ダイアグラムのコピーの束全体が収集されます。これはおそらく必要ないかもしれませんが、ほとんどの場合、それらを「マスター」にしたいと思うでしょう。