Normalerweise sollen die Anwender nur über die vorgegebenen Schnittstellen Daten aus der Datenbank auslesen oder ändern. Daher arbeiten etliche Anwendungen über SQL-Funktionsuser oder Application-Roles. Wenn die Kunden aber einen Teil der Daten direkt lesen müssen, dann lohnt es sich dafür spezielle Views einzurichten, die quasi eine Schnittstelle liefern, die man über die Versionszyklen konstant halten kann, egal wie sich die zugrunde liegende Tabellenstruktur verändert. Dann kann man Datenbank-Rollen einrichten, die auf diese Views Zugriff haben. Zu Beginn der Woche diskutierten wir in einem Kurs, ob man die Rechte für die Gruppe dann automatisch generieren kann.

Wenn man die Views anhand des Names erkennen kann, dann ja. Dazu muss man die Systemtabellen auslesen und eine entsprechende Rolle anlegen. Die GRANT-Befehle kann man ganz einfach generieren. Dabei muss man nur beachten, dass seit SQL-Server-2005 immer "Schema.Name" angegeben wird, nicht mehr "Owner.Name":

SELECT N'GRANT SELECT ON ['+s.name+N'].['+o.name+N'] TO [Reader_Role] -- Owner: '
+user_name(ISNULL(o.principal_id,s.principal_id)) AS [SqlCmd]
FROM sys.objects AS o
JOIN sys.schemas AS s
ON (o.schema_id=s.schema_id)
WHERE o.type = 'V'
AND o.name LIKE 'Reader[_]%'

Im folgenden Beispiel wird auch noch die Rolle angelegt und der komplete SQL-Batch als Ergebnis geliefert:

SELECT [SqlCmd]
FROM (
SELECT 0 AS OrderNo, N'IF user_id(''[Reader_Role]'') IS NULL
CREATE ROLE [Reader_Role] AUTHORIZATION Thomas;' AS [SqlCmd]
UNION ALL
SELECT ROW_NUMBER() OVER (ORDER BY s.name+o.name) AS OrderNo,
N'GRANT SELECT ON ['+s.name+N'].['+o.name+N'] TO [Reader_Role]; – Owner: '
+user_name(ISNULL(o.principal_id,s.principal_id)) AS [SqlCmd]
FROM sys.objects AS o
JOIN sys.schemas AS s
ON (o.schema_id=s.schema_id)
WHERE o.type = 'V'
AND o.name LIKE 'Reader[_]%'
) AS T
ORDER BY OrderNo

Das Ergebnis muss man dann nur noch auffangen und von einem Benutzer mit ausreichenden Rechten ausführen lassen, z.B. dem Besitzer der Datenbank oder einen anderen DDL-Admin. Das sieht zum Beispiel so aus:

IF user_id('[Reader_Role]') IS NULL
CREATE ROLE [Reader_Role] AUTHORIZATION Thomas;
GRANT SELECT ON [Music].[Reader_Albums] TO [Reader_Role]; – Owner: Thomas
GRANT SELECT ON [Music].[Reader_Songs] TO [Reader_Role]; – Owner: Thomas
GRANT SELECT ON [Music].[Reader_Singers] TO [Reader_Role]; – Owner: Thomas

Viel Erfolg.