6

我正在使用 Sql Server 2008 并且有一个在内部使用 sp_executesql 的过程。通过 ASP.NET 执行过程时,我不断收到以下错误:

对象“MyTable”、数据库“MyDatabase”、模式“dbo”的 SELECT 权限被拒绝。

我对此进行了大量研究,大多数人都指出我需要授予对我的动态查询读取的基础表的选择权限。好吧,我已经这样做了,但它似乎仍然不起作用:

select object_name(major_id) as object,
 user_name(grantee_principal_id) as grantee,
 user_name(grantor_principal_id) as grantor,
 permission_name,
 state_desc
from sys.database_permissions
where major_id = object_id('User') and 
class = 1
结果:
MyTable 公共 dbo SELECT GRANT
MyTable 来宾 dbo SELECT GRANT
MyTable myuser dbo SELECT GRANT
MyTable NT AUTHORITY\NETWORK SERVICE dbo SELECT GRANT

如您所见,我在尝试授予基础表上的选择时已经过分了。我什至重写了我的过程,以便它只在动态 sql 中引用 MyTable。我什至已授予上述所有用户对进程的“执行”权限......不走运。

上面的“myuser”是我在 web.config 中的连接字符串中的用户名。

我在这里错过了什么吗?

谢谢!戴夫

4

2 回答 2

5

我想到了。为遇到此问题的其他人发布此内容。

1) 首先,我注意到我的 dbo 用户没有与之关联的登录名。您可以通过右键单击 dbo 用户的 Security/Users 文件夹中的 dbo 用户并单击“属性”来看到这一点。在灰色区域中,您应该有一个用户名 (dbo) 和登录名 (sa)。我认为这通常发生在您恢复数据库或其他东西时(不确定)。无论如何,如果您没有看到登录名,只需在存在问题的数据库中运行脚本:

sp_changedbowner 'sa'

这只是使 dbo 成为数据库的所有者(或类似的东西)。我发现这一点的原因是因为我尝试通过这个 gui 界面保存一些权限,例如“db_datareader”、“db_datawriter”,但抛出了一个错误,说需要登录名。我认为 dbo 应该检查 db_owner (我的),我认为这胜过所有其他人。

2)为了让我的proc正常工作,我必须在proc的末尾添加“with execute as owner”。我之前尝试过这个,但由于我的第一个问题#1,它认为它不起作用。Procs 通常在 proc 的所有者下运行,但不是在 procs 内运行动态 sql。这些在执行 proc 的用户的上下文中运行。对我来说这很奇怪,因为我认为我需要在动态 sql 中添加它(我尝试过),但它需要在 proc 本身中(图?)

3)运行这个脚本也可能不会有什么坏处:

将“MyTable”上的选择授予“MyUser”

对于动态 sql 中使用的每个表。

希望这可以帮助...

以下是对同一问题的一些参考:

http://www.jimmcleod.net/blog/index.php/2007/05/15/sp_executesql-breaks-chain-of-ownership-in-sql-server-2000/

http://kbalertz.com/301299/Security-Context-Dynamic-Statements-Inside-Stored-Procedure.aspx

http://www.mssqltips.com/tipprint.asp?tip=1822

于 2010-02-04T20:42:18.487 回答
0

对我有帮助的是:

在 SQL Management Studio 中,右键单击存储过程并选择“属性”,然后在“权限”页面上向相关用户授予权限。相关用户取决于您的 SQL 连接字符串:如果您使用 Windows 身份验证,则它是 Windows 用户(如果这样配置,可能是 ASPNET);否则就是您在连接字符串中指定的 SQL 用户。您需要授予的权限是执行权限。

于 2011-10-28T20:54:45.663 回答