Sql 服务器主体";XYuser";“无法访问数据库”;Ydb“;在当前的安全环境下 系统规格

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

在名为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.
在谷歌搜索错误消息后,我执行了以下修复

  • 已从中删除用户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