Now, back to our regularly scheduled technical content. About schemas, users, and owners.
Although Ed originally created the table, since Fred is the schema owner, Fred owns to table. Ed can get ownership of the table in either of two ways.
1. Someone with authority can alter the table's owner2. Someone with authority can give Ed "take ownership" permission on the table
Until Ed has "take ownership" permission, he does not and cannot "own" the table he just created.
There are two ways to tell who owns a table. If you know who the schema owner is, "select * from sys.tables" produces a column named principal_id. If the principal_id is NULL, then the table is owned by the schema owner. If the principal_id is not NULL, the table has a specific owner. The other way is to use the OBJECTPROPERTY function and look for the property 'OwnerId'. This gives the exact owner, whether or not it's the schema owner.
This matters because, if you change the schema owner, the owner of the tables with NULL in prinipal_id changes. The owner of "specific-owner" tables does NOT change. So if the schema owner changes, say, to DBO, then DBO owns all the tables in the schema. BUT does not own Ed's table.
This whole thing is made possible because of the interesting meld that had to happen between a SQL Server-specific feature (ownership chains) and a new SQL2003-compliant feature (separation of users and schemas). Is this clear as a bell, now?
Just in case you don't believe it, code below (picks up where other code left off):
-- snip (when I left off, I was Ed)-- ed cannot get ownership of table-- this failsalter authorization on object::fredstuff.edtab to edgo
-- back to dbosetuser go
-- dbo can give the table to ed-- alter authorization on object::fredstuff.edtab to ed-- go
-- or dbo can give ed 'take ownership' permissiongrant take ownership on fredstuff.edtab to edgo
setuser 'ed'go
-- now this works for ed, because he has 'take ownership'alter authorization on object::fredstuff.edtab to edgo
-- now ed can SELECT the tableselect * from fredstuff.edtabgo
-- ed creates another table in the schemacreate table fredstuff.table1 (id int)go
setuser go
-- note that edtab has a principal_id (ed's)-- note that table1 (owned by schema owner) has NULL principal_idselect * from sys.database_principalsselect * from sys.tablesgo
-- owned by 'fred' (schema owner)select objectproperty(object_id('fredstuff.table1'), 'OwnerId')-- owned by 'ed'select objectproperty(object_id('fredstuff.edtab'), 'OwnerId')go
setuser 'fred'go
-- so can fred SELECT both tables-- because fred is the schema ownerselect * from fredstuff.edtabselect * from fredstuff.table1go
alter authorization on schema::fredstuff to dbogo
setuser 'fred'go-- no access for fred on this tableselect * from fredstuff.edtab-- access for fred on this tableselect * from fredstuff.table1go
setuser gosetuser 'ed'go-- access for ed, he's still the ownerselect * from fredstuff.edtab-- never had access to this tableselect * from fredstuff.table1go
-- note that edtab has a principal_id (ed's)-- note that table1 (owned by schema owner) has NULL principal_idselect * from sys.tablesgo
select * from sys.database_principals-- owned by 'dbo' (schema owner), this changedselect objectproperty(object_id('fredstuff.table1'), 'OwnerId')-- owned by 'ed', this did not change
select objectproperty(object_id('fredstuff.edtab'), 'OwnerId')go
-- snip --
Theme design by Jelle Druyts
Pick a theme: BlogXP sqlx BlogXP sqlx
Powered by: newtelligence dasBlog 2.0.7226.0
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.
© Copyright 2008, Bob Beauchemin
E-mail