For objects that may have column permissions, such as tables or views, having DENY or GRANT object permissions requires REVOKE to maintain column permissions. The following is a working example tested on SQL Server 2008, which demonstrates when a record with state R can exist in sys.database_permissions . If the order of the GRANT and REVOKE canceled, a record with state R not saved.
https://gist.github.com/mches/d2282946fbe7f50a708b
CREATE USER RevokeTestUser WITHOUT LOGIN; REVOKE CONNECT TO RevokeTestUser AS dbo; CREATE TABLE dbo.RevokeTest ( col int NOT NULL ); GRANT SELECT ON dbo.RevokeTest TO RevokeTestUser AS dbo; REVOKE SELECT ON dbo.RevokeTest (col) TO RevokeTestUser AS dbo; SELECT * FROM sys.database_permissions WHERE grantee_principal_id = DATABASE_PRINCIPAL_ID(N'RevokeTestUser'); DROP USER RevokeTestUser; DROP TABLE dbo.RevokeTest;
These are the results of the SELECT :
class class_desc major_id minor_id grantee_principal_id grantor_principal_id type permission_name state state_desc 1 OBJECT_OR_COLUMN 1081939822 0 31 1 SL SELECT G GRANT 1 OBJECT_OR_COLUMN 1081939822 1 31 1 SL SELECT R REVOKE
source share