存储过程和权限 - EXECUTE足够吗?

时间:2010-09-28 17:26:51

标签: sql-server stored-procedures permissions

我有一个SQL Server 2008数据库,其中对基础表的所有访问都是通过存储过程完成的。一些存储过程只是从表中SELECT记录,而其他存储过程是UPDATE,INSERT和DELETE。

如果存储过程更新了表,那么执行存储过程的用户是否还需要对受影响的表具有UPDATE权限,或者他们对存储过程具有EXECUTE权限这一事实呢?

基本上我想知道给用户EXECUTE权限是否足够,或者我是否需要为表提供SELECT,UPDATE,DELETE和INSERT权限才能使存储过程正常工作。谢谢。

[编辑] 在我的大多数存储过程中,确实看起来EXECUTE就足够了。但是,我确实发现在使用“执行sp_Executesql”的存储过程中,EXECUTE是不够的。涉及的表需要具有在“sp_Executesql”中执行的操作的权限。

5 个答案:

答案 0 :(得分:24)

如果表和proc具有相同的所有者,则不会检查表的权限(包括DENY)。只要模式具有相同的所有者,它们也可以使用不同的模式。

请参阅MSDN上的Ownership chaining

根据已删除答案的评论进行编辑。

除非使用EXECUTE AS,否则上下文始终是当前登录:仅检查引用的对象DML权限。在存储过程中尝试OBJECT_ID(可引用),其中没有权限分配给referencedtable。它给出了NULL。如果由存储过程的所有者执行,那么它将给出一个值,因为owener拥有可引用的权限

答案 1 :(得分:12)

对存储过程执行权限就足够了。

CREATE TABLE dbo.Temp(n int)

GO
DENY INSERT ON dbo.Temp TO <your role>
GO
CREATE PROCEDURE dbo.SPTemp(@Int int)
AS

INSERT dbo.Temp
SELECT  @Int 

GO

GRANT EXEC ON dbo.SPTemp TO <your role>

GO

然后(非db_owner)用户将拥有以下权限:

EXEC dbo.SPTemp 10
GO

INSERT dbo.Temp --INSERT permission was denied on the object 'Temp'
SELECT  10

但是,如果dbo.SPTemp中存在尝试插入dbo.Temp的动态SQL,则会失败。在这种情况下,需要授予对表的直接许可。

答案 2 :(得分:3)

也许你可以使用

  

“with execute as owner”

创建存储过程时,如下所示:

create procedure XXX
with execute as owner
as
begin
...
end
go

然后,您只需向用户授予存储过程EXECUTE的{​​{1}}权限。

答案 3 :(得分:2)

执行插入,更新或删除的存储过程的执行权限就足够了。您不需要在表级别授予这些权限。事实上,我会劝阻这种做法。使用存储过程可以更好地控制更改的发生方式。例如,您可能希望在允许更新之前进行一些检查。使用存储过程还可以帮助防止重大事故 - 比如删除表中的所有行,因为有人忘记了WHERE子句!

答案 4 :(得分:1)

非常感谢你!我遇到了类似的问题。这引出了我的答案。

我试图在存储过程中转换一个表,该存储过程调用嵌套在IF语句中的其他存储过程。

我的错误是

服务器主体“domain \ my_id”无法访问当前安全上下文下的数据库“2nd_DB”。

我已经给出了调用存储过程权限来执行truncate( EXECUTE AS SELF ),这会导致问题,因为SELF没有第二个DB的权限。我们的解决方案是将截断移动到另一个SP,包括EXECUTE AS SELF。我们现在调用截断SP,执行我们的数据处理,进行逻辑确定,并调用相应的第3个SP。