• Quick solution

    😎

    SELECT

    RoleName = max(pr.name )

    ,RoleType = max(pr.type_desc )

    ,perms = max( X.PERMS )

    ,ObjectName = max(s.name + '.' + o.name )

    ,ObjectType = max(o.type_desc )

    ,Created = max(o.create_date )

    ,Altered = max(o.modify_date )

    FROM sys.database_principals AS pr

    JOIN sys.database_permissions pe ON pe.grantee_principal_id=pr.principal_id

    RIGHT JOIN sys.objects o ON pe.major_id=o.object_id

    JOIN sys.schemas s ON o.schema_id=s.schema_id

    CROSS APPLY

    (SELECT STUFF ( (SELECT NCHAR(44) + spe.permission_name

    FROM sys.database_permissions spe

    WHERE pe.grantee_principal_id = spe.grantee_principal_id

    FOR XML PATH(''),TYPE).value('.[1]','NVARCHAR(512)')

    ,1,1,'')) AS X(PERMS)

    WHERE is_ms_shipped=0

    AND o.TYPE IN ('FN','P','U','V','TF')

    AND pr.name IS NOT NULL

    GROUP BY pr.name

    ,pr.type_desc

    ,s.name + '.' + o.name

    ,pe.grantee_principal_id

    ,o.type

    ,o.name

    ,X.PERMS

    ORDER BY CASE WHEN pr.name IS NULL THEN 0 ELSE 1 END

    ,o.type

    ,o.name

    ,pr.name;