I recently encountered the problem that COUNT(*)
requires the user to have select permission on every single column of a table.
Even though the spec of 'COUNT(*)' explicitly says that
it does not use information about any particular column.
It just returns the number of rows in the result.
So if you want to count the number of of rows in a table as a restricted user you get permission exceptions.
Here is an example:
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;
After some testing I found that even
SELECT COUNT(1) FROM [Product]
does not work.
Can someone explain what the reasoning behind this behaviour is?
And what would be a workaround to allow the Intern
user to still get an accurate count of Product
.
Update: I would be most interested in workarounds that the Intern could use. So even though creating a View would be best practice for the admin, the Intern does not have this option.
select count(1) ...
? – Apusselect count(name)
work? – Hyphaselect count(1) ...
also does not work. – AmourSELECT COUNT(name)
will not work since name might be null and so the result is incorrect. I know the example does not make perfect sense but basically I have a situation where I do not have a non null column available. – Amourselect count(nameSub) from (select ISNULL(name, ' ') as 'nameSub' from product) as TabSub
– HammadCOUNT(*)
means "the cardinality of a table expression" ...The table expression can be a table, derived table, (corelated) subquery, VIEW or a CTE... I wonder what happens if you add aIDENTITY(1, 1) PRIMARY KEY
column aswell without that you also dont really have a table...The idea behide that the optimizer should have statistics for the cardinality for that table then.. – CyanotypeIntern
should not see, and grantSELECT
permission on that. This way, queries work as normal without having to introduce circuitous and unintuitive workarounds and you do not need separateDENY
permissions per column either -- you don't have to grantSELECT
permission on the base table in the first place.COUNT(*)
is probably not the only thing that will behave inconveniently when you start denying access to individual columns. – InheritrixCOUNT(name)
example... doesSELECT COUNT(COALESCE(name, 'foo'))
work? – Lepton