链接服务器到 Azure 错误:“访问远程服务器被拒绝,因为不存在登录映射。”

Mik*_*ule 5 sql-server linked-server azure-sql-database

我正在设置从本地 SQL Server 到 MS Azure 上的数据库的链接服务器(见下文)。当非管理员用户通过链接服务器查询 Azure 数据库时,他们会得到:

Msg 7416, Level 16, State 2, Line 1 访问远程服务器被拒绝,因为不存在登录映射。

关于如何让这个工作的任何想法?

EXEC sp_addlinkedserver
@server='LincServer',                              
@srvproduct='',     
@provider='sqlncli',
@datasrc='myAzureDB.database.windows.net',
@location='',
@provstr='Encrypt=Yes;TrustServerCertificate=No;User ID=myAzureID',
@catalog='MyDB'

EXEC sp_addlinkedsrvlogin 
@rmtsrvname = 'LincServer',
@useself = 'false',
@rmtuser = 'myAzureID',
@rmtpassword = '########'
GO
Run Code Online (Sandbox Code Playgroud)

sep*_*pic 5

另一个答案是错误的,我想用重现代码和图片来反驳它。

这里的问题是参数@provstr,这是一个已知问题,这里描述了如何解决它:访问远程服务器被拒绝,因为不存在登录映射

问题:无法通过链接服务器 SQL Server 2005 运行查询。此问题仅发生在非系统管理员帐户上。

您收到以下消息:

消息 7416,级别 16,状态 2,第 1 行 对远程服务器的访问被拒绝,因为不存在登录映射。

原因:使用参数 @provstr 创建链接服务器并且使用本地 SQL Server 非管理员或非 Windows 帐户时,必须将参数“用户名”添加到 @provstr

解决:将“用户 ID=用户名”添加到链接服务器上的提供程序字符串中

EXEC master.dbo。sp_addlinkedserver @server = N'LinkServerName', @provider=N'SQLNCLI',@srvproduct = 'MS SQL Server', @provstr =N'SERVER=serverName\InstanceName; 用户ID=myUser'

EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname = N'LinkServerName',@locallogin = NULL,@useself = N'False',@rmtuser = N'myUser',@rmtpassword = N'*****'

OP已经做到了,他将远程登录包含到链接服务器定义中的提供者字符串中,所以我真的不知道还有什么会导致错误。

但现在我想证明,按照引用的指南,您可以消除错误,而按照其他答案,我们什么也解决不了。

这是我的重现代码。

我有 2 个服务器,默认实例和命名实例 (hp2\sql_2012_dev),我将使用 @provstr 将 hp2\sql_2012_dev 服务器链接到默认服务器,而不传入非管理员的 @provstr 远程登录 rmt,这将导致 OP所有非管理员用户都会出错。

我将使用 OP 的代码将所有本地登录映射到 1 个远程登录。然后我将尝试应用建议来单独映射有问题的登录,但这并不能解决问题。

然后,我将重新创建链接服务器,并使用提供程序字符串传递远程登录,这将解决问题,而无需任何额外的单独映射。

EXEC master.dbo.sp_addlinkedserver 
@server = N'LinkServer2012_rmt', 
@provider=N'SQLNCLI',
@srvproduct = '', 
@provstr=N'SERVER=hp2\sql_2012_dev';--don't pass User ID=rmt' now in order to cause the error

EXEC master.dbo.sp_addlinkedsrvlogin 
@rmtsrvname = N'LinkServer2012_rmt', 
@locallogin = NULL , 
@useself = N'False', 
@rmtuser = N'rmt', 
@rmtpassword = N'*****';
Run Code Online (Sandbox Code Playgroud)

此时非管理员登录 l 尝试选择:

select * 
from linkserver2012_rmt.master.dbo.spt_values; 
Run Code Online (Sandbox Code Playgroud)

并得到错误

消息 7416,级别 16,状态 2,第 1 行 对远程服务器的访问被拒绝,因为不存在登录映射。

好的,我们现在尝试单独映射它:

EXEC master.dbo.sp_addlinkedsrvlogin 
@rmtsrvname = N'LinkServer2012_rmt', 
@locallogin = N'l', 
@useself = N'False', 
@rmtuser = N'rmt', 
@rmtpassword = N'*****';
Run Code Online (Sandbox Code Playgroud)

并登录 l 重新尝试从链接服务器中进行选择,但他遇到了相同的错误

在此输入图像描述

此时,我删除并重新创建链接服务器,这次在链接服务器定义中传入 rmt 登录名,并将所有本地登录名映射到 rmt,而不进行任何单独的映射:

exec master.dbo.sp_dropserver @server=N'LinkServer2012_rmt', @droplogins='droplogins';

EXEC master.dbo.sp_addlinkedserver 
@server = N'LinkServer2012_rmt', 
@provider=N'SQLNCLI',
@srvproduct = '', 
@provstr=N'SERVER=hp2\sql_2012_dev;User ID=rmt'; --now pass in rmt login 

EXEC master.dbo.sp_addlinkedsrvlogin 
@rmtsrvname = N'LinkServer2012_rmt', 
@locallogin = NULL , 
@useself = N'False', 
@rmtuser = N'rmt', 
@rmtpassword = N'*****';
Run Code Online (Sandbox Code Playgroud)

这次非admin登录l就完全没有问题了:

在此输入图像描述

我不能认为我的帖子是OP问题的真正答案,也许原因是Azure,我无法测试它,因为我无法访问Azure服务器。但至少它在链接到本地​​实例时解决了同样的问题。

更新

在创建链接服务器时,尽量不要使用@provstr,如下所示:

EXEC sp_addlinkedserver   
   @server=N'LincServer', 
   @srvproduct=N'',
   @provider=N'SQLNCLI', 
   @datasrc=N'myAzureDB.database.windows.net',
   @catalog='MyDB';
Run Code Online (Sandbox Code Playgroud)