MSDN documentation for sys.database_permissions表示状态列可以是'G','D','R'或'W'。 “ R”值具有“ REVOKE”的描述,这听起来像具有该值的行将对应于已撤消的许可。但是,据我所知,从the docs for REVOKE撤消权限会完全将其删除,因此我希望可以从sys.database_permissions中删除​​该行。当我测试授予然后撤销许可时,就是这种情况。在GRANT之后,权限将显示在该视图中,在REVOKE之后,权限将消失。

我的问题:在什么情况下该视图会包含状态设置为“ R”的行?我之所以这样问是因为我不确定在代码中检查此视图时是否需要处理'R'行。

我可以想到可能发生这种情况的一些潜在情况,但尚未找到任何确认:


如果您授予了一些总括权限,然后撤销了总括权限所隐含的更细化的权限(细化权限将显示为“ R”),则可能会出现“ R”行。到目前为止,我还没有找到任何此类权限。
在SQL处理REVOKE命令时,“ R”行可能会非常短暂地出现,然后整行消失。我还没有观察到这种现象,但是大概只有很小的时间窗口会出现。

最佳答案

对于具有列权限的对象(例如表或视图),
DENYGRANT对象权限的存在要求REVOKE才能保留列权限。下面是一个在SQL Server 2008上测试的工作示例,该示例演示何时状态R的记录可以存在于sys.database_permissions中。如果GRANTREVOKE语句的顺序颠倒,则状态为R的记录将不会保留。

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;


这些是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

08-27 03:53