2017-02-06 1 views
0

ich die Datenbankrollen eines bestimmten Benutzers über gespeicherte Prozedur mit dem immer folgend:Return Datenbankrollen ein Benutzer ist kein Mitglied der

USE SQLEXP_ALLEN 
GO 

SELECT 
    DP1.name AS RoleName, 
    ISNULL(DP2.name, 'No members') AS UserName 
FROM 
    sys.database_role_members AS DRM 
RIGHT OUTER JOIN 
    sys.database_principals AS DP1 ON DRM.role_principal_id = DP1.principal_id 
LEFT OUTER JOIN 
    sys.database_principals AS DP2 ON DRM.member_principal_id = DP2.principal_id 
WHERE 
    DP1.type = 'R' 
    AND DP2.name = @username 
ORDER BY 
    DP1.name; 

Aber ich kann nicht scheinen, um herauszufinden, wie zu kommen mit Rollen, zu denen der Benutzer kein Mitglied ist. HILFE!

+0

Sie, wo Prädikat von DP2.Name Ihren linken Join in einen inneren Join verwandelt hat. –

Antwort

0

ich wahrscheinlich nicht brauchen, so viele CTEs aber es erklärt die Logik: 1) Selct alle Rollen 2) Wählen Sie alle Benutzer 3) Kreuz verbinden alle Kombinationen zu erhalten. 4) Linke äußere Verbindung zu Rollenmitgliedern, um zu sehen, welche nicht Mitglieder sind. Sie können jeden CTE anpassen, um zu erhalten, was Sie brauchen.

WITH Roles (RoleID, RoleName) 
     AS (SELECT rol.principal_id, 
        rol.name 
      FROM sys.database_principals rol 
      WHERE type = 'R' 
     ), 
    Users (UserID, Username) 
     AS (SELECT princ.principal_id , 
        princ.name 
      FROM  sys.database_principals princ 
      WHERE type IN ('U', 'G') 
     ), 
    UsersAllRoles (UserID, UserName, RoleID, RoleName) 
     AS (SELECT Users.UserID, Users.Username, Roles.RoleID, 
      Roles.RoleName 
      FROM  Users 
        CROSS JOIN Roles 
     ) 

SELECT uar.UserID , 
    uar.UserName , 
    uar.RoleID , 
    uar.RoleName , 
    drm.role_principal_id 
FROM UsersAllRoles uar 
    LEFT OUTER JOIN sys.database_role_members drm 
    ON uar.UserID =drm.member_principal_id 
    AND uar.RoleID = drm.role_principal_id 
WHERE drm.member_principal_id IS NULL; 
Verwandte Themen