Microsoft SQL Server Management Studio 9.00.4035.00
Microsoft Analysis Services Client Tools 2005.090.4035.00
Microsoft Data Access Components (MDAC) 2000.085.1132.00
(xpsp.080413-0852)
Microsoft MSXML 2.6 3.0 4.0 5.0 6.0
Microsoft Internet Explorer 7.0.5730.13
Microsoft .NET Framework 2.0.50727.1433
Operating System 5.1.2600
在名为 BHAVMSQL02 的SQL Server 2005上,我有两个数据库 Mattercentre_dev 和 CMSNET_DEV 。 Mattercentre_dev 有一个存储过程,可以从 CMSNET_DEV 中的表构建列表。存储过程看起来 像这样...
USE [Mattercentre_dev]
GO
/****** Object: StoredProcedure [dbo].[UDSPRBHPRIMBUSTYPE]
Script Date:02/12/2009 10:18:10 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER OFF
GO
ALTER PROCEDURE [dbo].[UDSPRBHPRIMBUSTYPE] WITH EXECUTE AS 'Readuser' AS
DECLARE @SERVERNAME nvarchar(30)
DECLARE @DBASE nvarchar(30)
DECLARE @SQL nvarchar(2000)
SET @SERVERNAME = Convert(nvarchar,
(SELECT spData FROM dbSpecificData WHERE spLookup = 'CMSSERVER'))
SET @DBASE = Convert(nvarchar,
(SELECT spData FROM dbSpecificData WHERE spLookup = 'CMSDBNAME'))
SET @SQL =
'SELECT
null as Code
, ''(not specified)'' as Description
UNION SELECT
clnt_cat_code as Code
, clnt_cat_desc as Description
FROM '
+ @SERVERNAME + '.' + @DBASE + '.dbo.hbl_clnt_cat
WHERE
inactive = ''N''
ORDER BY Description'
PRINT @SQL
EXECUTE sp_executeSQL @SQL
@SERVERNAME == 'BHAVMSQL02'
@DBASE == 'CMSNET_DEV'
执行存储过程时,出现以下错误消息...
The server principal "ReadUser" is not able to access the database "CMSNET_DEV" under the current security context.
在Google上搜索错误消息后,我执行了以下修复...
从BHAVMSQL02设置ReadUser - > 安全 - >登录以下内容 设置...
一般
登录名 - readUser
密码 - xxxxxxxxxxxx
确认 - xxxxxxxxxxxx
默认db - master
默认lg - 英国英语
其他一切 - 取消设置
服务器角色 仅公开集
用户映射
CMSNET_DEV - ReadUser - dbo
数据库角色成员资格 - db_owner,public
Mattercentre_dev - ReadUser - dbo
数据库角色成员资格 - db_owner,public
然后我运行了以下脚本......
ALTER DATABASE CMSNET_DEV SET TRUSTWORTHY ON
GO
ALTER DATABASE mattercentre_dev SET TRUSTWORTHY ON
GO
我重新运行存储过程并再次执行它,我仍然有相同的 错误信息。
我在Stack Overflow和建议的解决方案中看到了这个问题 与我自己的相似。
答案 0 :(得分:2)
当存储过程包含动态SQL时,您无法使用所有权链接,即这样做会破坏所有权链。
为了使其正常工作,您需要使用证书对存储过程进行签名。
以下是一篇精彩的文章,其中包含有关签署存储过程的说明。
http://www.sommarskog.se/grantperm.html
更详细地看一下,您使用“执行为子句”的事实应该否定由于合并动态SQL而导致所有权链被破坏的事实。
考虑到这一点,可能的问题是由于某种原因,登录“ReadUser”没有对相关数据库的适当读取访问权限,但是不应该是这种情况,因为登录是一个成员两个数据库中的db_owner角色。也就是说,如果数据库角色已从原始状态改变,那么这可能不成立。
为了测试问题是否与“ReadUser”登录无隔离,我建议创建一个新的SQL Server登录,并将登录映射到两个数据库(通过创建同名的数据库登录),并具有适当的读访问权限。然后修改存储过程以执行新登录。