sp_addlinkedsrvlogin (Transact-SQL)

适用范围:SQL Server

创建或更新 SQL Server 本地实例上的登录名与远程服务器上的安全帐户之间的映射。

Transact-SQL 语法约定

语法

sp_addlinkedsrvlogin
    [ @rmtsrvname = ] N'rmtsrvname'
    [ , [ @useself = ] 'useself' ]
    [ , [ @locallogin = ] N'locallogin' ]
    [ , [ @rmtuser = ] N'rmtuser' ]
    [ , [ @rmtpassword = ] N'rmtpassword' ]
[ ; ]

参数

[ @rmtsrvname = ] N'rmtsrvname'

登录映射应用于的链接服务器的名称。 @rmtsrvname为 sysname,无默认值。

[ @useself = ] 'useself'

确定是否通过模拟本地登录名或显式提交登录名和密码连接到 rmtsrvname@useself为 varchar(8),默认值为 true.

  • 一个值 true ,该值指定登录名使用自己的凭据连接到 @rmtsrvname,并 忽略@rmtuser@rmtpassword 参数。
  • false指定@rmtuser和@rmtpassword参数用于连接到指定@locallogin的@rmtsrvname

如果 @rmtuser@rmtpassword 设置为 NULL,则不会使用登录名或密码连接到链接服务器。

[ @locallogin = ] N'locallogin'

本地服务器上的登录名。 @locallogin为 sysname,默认值为 NULL. NULL 指定此项适用于连接到 @rmtsrvname的所有本地登录名。 NULL否则,@locallogin可以是 SQL Server 登录名或 Windows 帐户。 Windows 帐户必须直接或通过 Windows 组中的成员身份访问 SQL Server。

[ @rmtuser = ] N'rmtuser'

用于在何时连接到 @rmtsrvname @useself false的远程登录名。 @rmtuser为 sysname,默认值为 NULL. 当远程服务器是不使用 Windows 身份验证的 SQL Server 实例时, @rmtuser 是 SQL Server 登录名。

[ @rmtpassword = ] N'rmtpassword'

@rmtuser关联的密码。 @rmtpassword为 sysname,默认值为 NULL.

返回代码值

0(成功)或 1(失败)。

注解

当用户登录到本地服务器并执行分布式查询,以访问链接服务器上的表时,本地服务器必须登录链接服务器上,代表该用户访问该表。 用于 sp_addlinkedsrvlogin 指定本地服务器用于登录到链接服务器的凭据。

注意

若要在链接服务器上使用表时创建最佳查询计划,查询处理器必须具有来自链接服务器的数据分发统计信息。 对表的任何列具有有限权限的用户可能没有足够的权限来获取所有有用的统计,并且可能会收到效率较低的查询计划和经历不佳的性能。 如果链接服务器是 SQL Server 的实例,若要获取所有可用的统计信息,则用户必须拥有该表或 sysadmin 固定服务器角色的成员db_owner固定数据库角色或链接服务器上的db_ddladmin固定数据库角色。 SQL Server 2012 SP1 (11.0.3x) 修改获取统计信息的权限限制,并允许具有 SELECT 权限的用户访问 DBCC SHOW_STATISTICS提供的统计信息。 有关详细信息,请参阅 DBCC SHOW_STATISTICS“权限”部分。

通过执行 sp_addlinkedserver自动创建本地服务器上的所有登录名和链接服务器上的远程登录名之间的默认映射。 默认映射表示,SQL Server 代表登录名连接到链接服务器时使用本地登录名的用户凭据。 这相当于为链接服务器执行sp_addlinkedsrvlogin设置为 true ,而无需指定本地用户名。 仅用于 sp_addlinkedsrvlogin 更改默认映射或为特定本地登录名添加新映射。 若要删除默认映射或任何其他映射,请使用 sp_droplinkedsrvlogin

SQL Server 无需用于 sp_addlinkedsrvlogin 创建预先确定的登录映射,而是可以在存在以下所有条件时自动使用发出查询的用户的 Windows 安全凭据(Windows 登录名和密码)连接到链接服务器:

  • 用户使用 Windows 身份验证模式连接到 SQL Server。

  • 在客户端和发送服务器上安全帐户委托是可用的。

  • 提供程序支持 Windows 身份验证模式;例如,在 Windows 上运行的 SQL Server。

注意

无需为单跃点方案启用委派,但多跃点方案需要它。

通过使用在 SQL Server 的本地实例上定义的 sp_addlinkedsrvlogin 映射对链接服务器执行身份验证后,远程数据库中各个对象的权限由链接服务器而不是本地服务器确定。

sp_addlinkedsrvlogin 不能从用户定义的事务中执行。

权限

要求对服务器拥有 ALTER ANY LOGIN 权限。

示例

A. 使用自己的用户凭据将所有本地登录名连接到链接服务器

以下示例将创建一个映射,以确保所有到本地服务器的登录都使用其各自的用户凭据连接到链接服务器 Accounts

EXEC sp_addlinkedsrvlogin 'Accounts';

EXEC sp_addlinkedsrvlogin 'Accounts', 'true';

注意

如果为单个登录名创建了显式映射,则它们优先于该链接服务器可能存在的任何全局映射。

B. 使用不同的用户凭据将特定登录名连接到链接服务器

以下示例将创建一个映射,以确保 Windows 用户 Domain\Mary 使用登录名 Accounts 和密码 MaryP 连接到链接服务器 d89q3w4u

EXEC sp_addlinkedsrvlogin 'Accounts', 'false', 'Domain\Mary', 'MaryP', 'd89q3w4u';

注意

此示例不使用 Windows 身份验证。 密码未经加密而进行传输。 密码可能在数据源定义和脚本中可见,这些脚本保存在磁盘、备份和日志文件中。 在此类连接中,切勿使用管理员密码。 有关特定于环境的安全指南,请咨询您的网络管理员。

°C 将特定本地登录映射到远程服务器登录名

在某些情况下(例如使用 Azure SQL 托管实例),若要通过链接服务器在远程服务器上运行 Transact-SQL (T-SQL) 查询的 SQL 代理作业,需要在本地服务器上的登录名与有权执行 T-SQL 查询的远程服务器上的登录名之间创建映射。 当 SQL 代理作业通过链接服务器连接到远程服务器时,它会在远程登录的上下文中执行 T-SQL 查询,该查询必须具有执行 T-SQL 查询所需的权限。

如果要在 Azure SQL 托管实例映射 SQL 代理作业的登录名,则映射到远程登录名的本地登录名必须是 SQL 代理作业的所有者,除非 SQL 代理作业为 sysadmin,在这种情况下,应映射所有本地登录名。 有关详细信息,请查看具有Azure SQL 托管实例的 SQL 代理作业。

在本地服务器上运行以下命令,在连接到链接服务器时将本地登录local_login_name名映射到远程服务器remote_server登录login_name名:

EXEC master.dbo.sp_addlinkedsrvlogin
@rmtsrvname = N'<remote_server>',
@useself = N'False',
@locallogin = N’<local_login_name>’,
@rmtuser = N'<login_name>',
@rmtpassword = '<login_password>'

D. 将所有本地登录名映射到远程服务器登录名

通过设置为,localloginNULL可以将所有本地登录名映射到远程服务器上的登录名。

执行 sysadmin 拥有的 Azure SQL 托管实例 SQL 代理作业,通过链接服务器查询远程服务器时,需要将所有本地登录名映射到远程服务器。 有关详细信息,请查看具有Azure SQL 托管实例的 SQL 代理作业。 当 SQL 代理作业通过链接服务器连接到远程服务器时,它会在远程登录的上下文中执行 T-SQL 查询,该查询必须具有执行 T-SQL 查询所需的权限。

在本地服务器上运行以下命令,在连接到链接服务器时将所有本地登录名映射到远程服务器remote_server登录login_name名:

EXEC master.dbo.sp_addlinkedsrvlogin
@rmtsrvname = N'<remote_server>',
@useself = N'False',
@locallogin = NULL,
@rmtuser = N'<login_name>',
@rmtpassword = '<login_password>'

E. 检查链接的登录名

以下示例显示了已为链接服务器映射的所有登录名:

SELECT s.name AS server_name, ll.remote_name, sp.name AS principal_name
FROM sys.servers s
INNER JOIN sys.linked_logins ll
    ON s.server_id = ll.server_id
INNER JOIN sys server_principals sp
    ON ll.local_principal_id = sp.principal_id
WHERE s.is_linked = 1;