Es hört sich so an, als gäbe es verschiedene Eigentümer der Prozedur sowie des zugrunde liegenden Objekts, das von SELECT abgefragt wird. Dies alles hat mit Besitzerketten zu tun . Im folgenden Beispiel finden Sie eine kurze Erklärung und Demonstration dessen, wovon ich spreche:
use YourTestDatabase;
go
create login TestLogin1
with
password = 'password',
check_policy = off;
go
create user TestUser1
for login TestLogin1;
go
create table Table1
(
id int identity(1, 1) not null,
SomeString varchar(30) not null
default replicate('a', 30)
);
go
insert into Table1
values(default);
go 10
create proc Proc1
as
select *
from Table1;
go
grant execute
on Proc1
to TestUser1;
go
-- this works because permissions aren't checked
-- on Table1. That is why TestUser1 can get the
-- result set without SELECT permissions on Table1
execute as user = 'TestUser1';
go
exec Proc1;
go
revert;
go
-- let's change the owner of Proc1 so that the
-- ownership chain is broken and permissions are
-- checked on Table1
alter authorization
on Proc1
to TestUser1;
go
-- this no longer works because permissions are now
-- checked on Table1, which TestUser1 does not have
-- SELECT permissions on
execute as user = 'TestUser1';
go
exec Proc1;
go
revert;
go
Wenn Sie den Besitz Ihrer Objekte herausfinden möchten, können Sie die folgende Abfrage ausführen (natürlich mit Änderung der WHERE-Klausel, um Ihre spezifischen Objektnamen einzuschließen):
select
o.name,
o.type_desc,
case
when o.principal_id is null
then sp.name
else dp.name
end as principal_name
from sys.objects o
inner join sys.schemas s
on o.schema_id = s.schema_id
left join sys.database_principals dp
on o.principal_id = dp.principal_id
left join sys.database_principals sp
on s.principal_id = sp.principal_id
where o.name in
(
'Table1',
'Proc1'
);