【发布时间】:2020-01-02 11:34:20
【问题描述】:
我最近遇到COUNT(*) 要求用户对表的每一列都有选择权限的问题。
尽管spec of 'COUNT(*)' 明确表示
它不使用任何特定列的信息。
它只返回结果中的行数。
因此,如果您想将表中的行数计算为受限用户,则会出现权限异常。
这是一个例子:
CREATE TABLE [Product]
([name] nvarchar(100) null, [price] float)
CREATE USER Intern WITHOUT LOGIN;
DENY SELECT ON [Product] (price) TO Intern;
EXECUTE AS Intern;
-- Fails with "The SELECT permission was denied on the column 'price' of the object 'Product'"
SELECT COUNT(*) FROM [Product];
REVERT;
经过一些测试,我发现即使
SELECT COUNT(1) FROM [Product] 不起作用。
有人可以解释这种行为背后的原因是什么吗?
什么是允许Intern 用户仍然获得Product 的准确计数的解决方法。
更新: 我对实习生可以使用的解决方法最感兴趣。因此,即使创建视图是管理员的最佳实践,实习生也没有此选项。
【问题讨论】:
-
你试过
select count(1) ...吗? -
select count(name)工作吗? -
最好的解决方案可能是创建一个明确排除
Intern不应该看到的列的视图,并授予SELECT权限。这样,查询就可以正常工作,而不必引入迂回和不直观的变通办法,并且您也不需要每列单独的DENY权限——您不必首先授予基表上的SELECT权限。当您开始拒绝访问各个列时,COUNT(*)可能不是唯一会造成不便的事情。 -
@JeroenMostert 你说得对,创建视图是最好的解决方案,我最感兴趣的是实习生如何解决这个问题,他大概无法创建视图。
-
@pascalsanchez 您将空名称转换为其他名称的解决方案。这些解决方案唯一不是最佳的部分是性能稍差。
标签: sql sql-server tsql sql-server-2017