{"id":2814,"date":"2009-05-16T10:54:30","date_gmt":"2009-05-16T08:54:30","guid":{"rendered":"http:\/\/www.glorf.it\/blog\/?p=2814"},"modified":"2009-05-19T12:42:59","modified_gmt":"2009-05-19T10:42:59","slug":"standardisierte-rechte-generieren","status":"publish","type":"post","link":"http:\/\/www.glorf.it\/blog\/2009\/05\/16\/sql-talk\/standardisierte-rechte-generieren","title":{"rendered":"standardisierte Rechte generieren"},"content":{"rendered":"<p>Normalerweise sollen die Anwender nur &#252;ber die vorgegebenen Schnittstellen Daten aus der Datenbank auslesen oder &#228;ndern. Daher arbeiten etliche Anwendungen &#252;ber SQL-Funktionsuser oder Application-Roles. Wenn die Kunden aber einen Teil der Daten direkt lesen m&#252;ssen, dann lohnt es sich daf&#252;r spezielle Views einzurichten, die quasi eine Schnittstelle liefern, die man &#252;ber die Versionszyklen konstant halten kann, egal wie sich die zugrunde liegende Tabellenstruktur ver&#228;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&#252;r die Gruppe dann automatisch generieren kann.<\/p>\n<p>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 &quot;Schema.Name&quot; angegeben wird, nicht mehr &quot;Owner.Name&quot;:<\/p>\n<p><code lang=\"SQL\">SELECT N'GRANT SELECT ON ['+s.name+N'].['+o.name+N'] TO [Reader_Role] -- Owner: '<br \/>\n\t\t+user_name(ISNULL(o.principal_id,s.principal_id)) AS [SqlCmd]<br \/>\n\tFROM sys.objects AS o<br \/>\n\tJOIN sys.schemas AS s<br \/>\n\t\tON (o.schema_id=s.schema_id)<br \/>\n\t\tWHERE o.type = &#x0027;V&#x0027;<br \/>\n\t\t  AND o.name LIKE &#x0027;Reader[_]%&#x0027;<\/code><\/p>\n<p>Im folgenden Beispiel wird auch noch die Rolle angelegt und der komplete SQL-Batch als Ergebnis geliefert:<\/p>\n<p><code lang=\"SQL\">SELECT [SqlCmd]<br \/>\nFROM (<br \/>\n\tSELECT 0 AS OrderNo, N&#x0027;IF user_id('&#x0027;[Reader_Role]'&#x0027;) IS NULL<br \/>\n\t\tCREATE ROLE [Reader_Role] AUTHORIZATION Thomas;&#x0027;  AS [SqlCmd]<br \/>\n\tUNION ALL<br \/>\n\tSELECT\tROW_NUMBER() OVER (ORDER BY s.name+o.name) AS OrderNo,<br \/>\n\t\t\tN&#x0027;GRANT SELECT ON [&#x0027;+s.name+N&#x0027;].[&#x0027;+o.name+N&#x0027;] TO [Reader_Role]; &#8211; Owner: &#x0027;<br \/>\n\t\t\t+user_name(ISNULL(o.principal_id,s.principal_id)) AS [SqlCmd]<br \/>\n\t\tFROM sys.objects AS o<br \/>\n\t\tJOIN sys.schemas AS s<br \/>\n\t\t\tON (o.schema_id=s.schema_id)<br \/>\n\t\tWHERE o.type = &#x0027;V&#x0027;<br \/>\n\t\t  AND o.name LIKE &#x0027;Reader[_]%&#x0027;<br \/>\n\t  \t\t  ) AS T<br \/>\nORDER BY OrderNo  <\/code><\/p>\n<p>Das Ergebnis muss man dann nur noch auffangen und von einem Benutzer mit ausreichenden Rechten ausf&#252;hren lassen, z.B. dem Besitzer der Datenbank oder einen anderen DDL-Admin. Das sieht zum Beispiel so aus:<\/p>\n<p><code lang=\"SQL\">IF user_id('[Reader_Role]') IS NULL<br \/>\n\t\tCREATE ROLE [Reader_Role] AUTHORIZATION Thomas;<br \/>\nGRANT SELECT ON [Music].[Reader_Albums] TO [Reader_Role]; &#8211; Owner: Thomas<br \/>\nGRANT SELECT ON [Music].[Reader_Songs] TO [Reader_Role]; &#8211; Owner: Thomas<br \/>\nGRANT SELECT ON [Music].[Reader_Singers] TO [Reader_Role]; &#8211; Owner: Thomas <\/code><\/p>\n<p>Viel Erfolg.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Normalerweise sollen die Anwender nur &#252;ber die vorgegebenen Schnittstellen Daten aus der Datenbank auslesen oder &#228;ndern. Daher arbeiten etliche Anwendungen &#252;ber SQL-Funktionsuser oder Application-Roles. Wenn die Kunden aber einen Teil der Daten direkt lesen m&#252;ssen, dann lohnt es sich daf&#252;r spezielle Views einzurichten, die quasi eine Schnittstelle liefern, die man &#252;ber die Versionszyklen konstant halten [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[3],"tags":[499,929],"_links":{"self":[{"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/posts\/2814"}],"collection":[{"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/comments?post=2814"}],"version-history":[{"count":12,"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/posts\/2814\/revisions"}],"predecessor-version":[{"id":2825,"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/posts\/2814\/revisions\/2825"}],"wp:attachment":[{"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/media?parent=2814"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/categories?post=2814"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.glorf.it\/blog\/wp-json\/wp\/v2\/tags?post=2814"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}