我们目前使用以下方法对链接服务器执行存储过程:
EXECUTE [LinkedServer].[DatabaseName].[dbo].[MyProcedure]
例如:
EXECUTE Screwdriver.CRM.dbo.GetCustomer 619
这很好用;通过链接服务器查询工作正常.
禁用已弃用的“远程访问”功能
显然有一个鲜为人知的,很少使用的功能,称为远程访问.除了say here:之外,微软几乎没有什么可说的
This configuration option is an obscure SQL Server to SQL Server communication feature that is deprecated, and you probably shouldn’t be using it.
Important
This feature will be removed in the next version of Microsoft SQL Server. Do not use this feature in new development work, and modify applications that currently use this feature as soon as possible. Use 07001 instead.
The remote access option only applies to servers that are added by using 07002, and is included for backward compatibility.
并从SQL Server 2000联机丛书:
07003 Note Support for remote servers is provided for backward compatibility only. New applications that must execute stored procedures against remote instances of SQL Server should use linked servers instead.
我们只添加了链接服务器,并且从未使用过这种“远程访问”功能,并且从未使用sp_addserver添加服务器.
我们都很好.对?
除了关闭远程访问打破了一切
审计员提到我们应该关闭远程访问功能:
>它是剪贴板上的安全复选框
>它已被微软弃用
>它几乎没用过
>我们不使用它
应该没事,对吧?
Microsoft文档how to turn off this hardly used feature:
Configure the remote access Server Configuration Option
06002
除非我们这样做:一切都变成了地狱:
Msg 7201, Level 17, State 4, Procedure GetCustomer, Line 1
Could not execute procedure on remote server 07005 because SQL Server is not configured for remote access. Ask your system administrator to reconfigure SQL Server to allow remote access.
为了绝对确定我正在使用链接服务器,我:
EXECUTE sp_dropserver @server='screwdriver', @dropLogins='droplogins'
EXECUTE sp_addlinkedserver N'screwdriver', N'SQL Server'
并重新运行我的过程调用:
EXECUTE Screwdriver.CRM.dbo.GetCustomer 619
Msg 7201, Level 17, State 4, Procedure GetCustomer, Line 1
Could not execute procedure on remote server ‘Screwdriver’ because SQL Server is not configured for remote access. Ask your system administrator to reconfigure SQL Server to allow remote access.
比失败还糟糕!?
我可以confirm服务器是链接服务器(并且不是“远程”服务器)使用:
SELECT SrvName, IsRemote
FROM master..sysservers
WHERE SrvName = 'Screwdriver'
Srvname IsRemote
----------- --------
screwdriver 0
或使用现代对象:
SELECT Name, Is_Linked
FROM sys.servers
WHERE Name = 'Screwdriver'
Name Is_linked
----------- --------
screwdriver 1
总结一下
我们现在正处于:
>我已禁用远程访问
>远程访问仅适用于通过sp_addserver添加的服务器
>它不适用于通过sp_addlinkedserver添加的服务器
>我正在访问通过sp_addlinkedserver添加的服务器
为什么不工作?
这让我想到了我的问题:
>如何对链接服务器执行存储过程?
结果如下:
>如何针对添加的(即“远程”)服务器执行存储过程?
奖金Chatter
使用sp_configure调整的远程访问配置选项也通过用户界面公开. SSMS UI错误地描述了该功能:
>它是措辞:允许远程连接到此服务器
>它应该是:允许从此服务器进行远程连接.
Books Online还错误地记录了该功能:
Allow remote connections to this server
Controls the execution of stored procedures from remote servers running instances of SQL Server. Selecting this check box has the same effect as setting the sp_configure remote access option to 1. Clearing it prevents execution of stored procedures from a remote server.
它应该是:
Allow remote connections
from this server
to
Controls the execution of stored procedures
to remote servers running instances of SQL Server. Selecting this check box has the same effect as setting the sp_configure remote access option to 1. Clearing it prevents execution of stored procedures
from
to a remote server.
from
现在微软的年轻人不记得他们从未接触过的20年前弃用的功能,这是有道理的.
来自BOL 2000的文档
SQL Server 2000是最后一次记录此功能.为了后代和调试目的而在此转载:
Configuring Remote Servers
A remote server configuration allows a client connected to one instance of Microsoft® SQL Server™ to execute a stored procedure on another instance of SQL Server without establishing another connection. The server to which the client is connected accepts the client request and sends the request to the remote server on behalf of the client. The remote server processes the request and returns any results to the original server, which in turn passes those results to the client.
If you want to set up a server configuration in order to execute stored procedures on another server and do not have existing remote server configurations, use linked servers instead of remote servers. Both stored procedures and distributed queries are allowed against linked servers; however, only stored procedures are allowed against remote servers.
07003 Note Support for remote servers is provided for backward compatibility only. New applications that must execute stored procedures against remote instances of SQL Server should use linked servers instead.
也可以看看
> Executing a Stored Procedure on a Linked Server
> SQL Linked server – Remote access error when executing SP
> SQL Server Error: Could not execute remote procedure
> MSDN Blogs: Unable to execute a remote stored procedure over a linked server(archive.is)
> Configure the remote access Server Configuration Option
> sp_addlinkedserver (Transact-SQL)
> sp_configure (Transact-SQL)
> Security Audit requires turning Remote Access off on all SQL 2005 and SQL 2008 Servers
备用标题:禁用SQL Server远程访问会中断存储过程.
最佳答案 那么,当你是对的时候,你是对的,无论是否记录在案.将远程访问设置为0(并重新启动)会导致使用四部分语法的远程存储过程调用失败,即使所有文档都表明链接服务器不应该失败.即使在SQL Server 2017(RTM CU12)的最新版本中也是如此,因此这不是特定于版本的.目前尚不清楚这是否是一个真正的限制,或者代码是否只是错误并基于远程访问功能检查阻止它,即使它在技术上有效.
涉及四部分名称(SELECT * FROM server.db.scheme.table)的查询不会失败,大概是因为这仅适用于链接服务器,并且从不涉及远程访问.
作为解决方法,您可以将调用更改为使用EXECUTE .. AT:
EXEC ('EXECUTE CRM.dbo.GetCustomer 619') AT Screwdriver
只要链接服务器启用了RPC Out选项(默认情况下由sp_addlinkedserver添加,没有特殊选项),它就会起作用.
不幸的是EXECUTE .. AT在涉及参数时不太方便,因为它只支持?句法:
EXEC ('EXECUTE CRM.dbo.GetCustomer @Customer=?', 619) AT Screwdriver
参数名称在这里是可选的,但我强烈建议使用它来保持可预测性.与EXECUTE相同 – 它是可选的,但它清楚地表明我们实际上正在运行任意查询,而不仅仅是调用存储过程.
如果您的过程具有OUTPUT参数,则此平面将不起作用; EXECUTE .. AT对此并不够聪明.您可以在调用中指定OUTPUT,但不会复制该值.这方面的解决方法超出了这个答案的范围,但它们不会很漂亮.
可能值得为此开一个suggestion,因为它似乎真的应该像记录的那样工作(如果微软想要永久摆脱远程访问,他们无论如何都需要).