Not sure if anyone else noticed this too, but Rick's Code seems to join incorrectly. He joins Principals to Permissions via this: Perm.major_ID = Prin.principal_id
However, Perm.major_ID is the Schema ID while Prin.principal_id is the User ID... Rick's code works because when you create a new database with a new scenario, that new SchemaID "TestSchema" is 5. The default UserID of this database will be 5 so
it does exist, and the join can happen. Then Rick never references the userID (principal_ID) again, so you wouldn't notice the flaw in logic. However, if you were to add ", USER_NAME(Prin.principal_id)" as a column, then you would realize the join
is actually on the default user who ran this script.
When you run this code on your own database, you probably have more schemas then you have users. So, there is no join because there is no instance where a schema ID matches a UserID. This is the reason why we keep getting nothing when we try to run Rick's
script.
Instead, try running this script, and swapping out the user names:
CREATE DATABASE listschema
go
USE listschema
go
CREATE SCHEMA TestSchema
go
CREATE USER TestUser WITHOUT LOGIN
go
GRANT SELECT ON SCHEMA::TestSchema TO TestUser
DENY INSERT ON SCHEMA::TestSchema TO TestUser
go
SELECT perm.state_desc, perm.permission_name, 'ON', perm.class_desc,
SCHEMA_NAME(perm.major_id),
'TO', USER_NAME(perm.grantee_principal_id)
FROM sys.database_permissions AS Perm
JOIN sys.database_principals AS Prin
ON Perm.grantee_principal_id = Prin.principal_id AND class_desc = 'SCHEMA'
WHERE major_id = SCHEMA_ID('TestSchema')
AND grantee_principal_id = user_id('TestUser')
--AND permission_name = 'SELECT'
go
USE tempdb
go
DROP DATABASE listschema