Sql 服务器主体";XYuser";“无法访问数据库”;Ydb“;在当前的安全环境下 系统规格
在名为BHAVMSQL02的SQL Server 2005上,我有两个数据库Mattercentre_dev和CMSNET_dev。Mattercentre_dev有一个存储过程,该存储过程从CMSNET_dev中的表生成列表。该存储过程看起来 像这样Sql 服务器主体";XYuser";“无法访问数据库”;Ydb“;在当前的安全环境下 系统规格,sql,sql-server,sql-server-2005,ssms,Sql,Sql Server,Sql Server 2005,Ssms,在名为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
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.
在谷歌搜索错误消息后,我执行了以下修复
- 已从中删除用户ReadUser BHAVMSQL02->数据库-> MatterCenter\u开发->安全->用户
- 从BHAVMSQL02设置ReadUser->
安全->使用以下命令登录
设置
一般性
登录名-readUser
密码-XXXXXXXXXX
确认-XXXXXXXXXX
默认数据库-主数据库
默认lg-英式英语
其他一切-未解决 服务器角色 只有公共集 用户映射 CMSNET_DEV-ReadUser-dbo
数据库角色成员资格-数据库所有者,公共 MatterCenter\u dev-ReadUser-dbo
数据库角色成员资格-数据库所有者,公共
ALTER DATABASE CMSNET_DEV SET TRUSTWORTHY ON
GO
ALTER DATABASE mattercentre_dev SET TRUSTWORTHY ON
GO
我重新运行了存储过程并再次执行了它,但仍然有相同的存储过程
错误消息
我在堆栈溢出和建议的解决方案中查找了这个问题
与我的类似。当存储过程包含动态SQL时,不能使用所有权链,即这样做会破坏所有权链 为了使其工作,您需要使用证书对存储过程进行签名 下面是一篇精彩的文章,其中包含对存储过程进行签名的说明 更详细地看一下这一点,使用“executeas子句”的事实应该否定所有权链因合并动态SQL而中断的事实 考虑到这一点,可能的原因是由于某种原因,登录名“ReadUser”对所讨论的数据库没有适当的读取权限,但是,鉴于登录名是两个数据库中db_所有者角色的成员,情况不应该如此。也就是说,如果数据库角色已从其原始状态更改,则这可能不成立 为了测试问题是否与“ReadUser”登录无关,我建议创建一个新的SQL Server登录,并使用适当的读取访问权限将登录映射到两个数据库(通过创建同名数据库登录)。然后修改存储过程以作为新登录名执行
ALTER DATABASE CMSNET_DEV SET TRUSTWORTHY ON
GO
ALTER DATABASE mattercentre_dev SET TRUSTWORTHY ON
GO