禁用 RPC 时如何在远程服务器上删除具有多个前缀的永久表

Posted

技术标签:

【中文标题】禁用 RPC 时如何在远程服务器上删除具有多个前缀的永久表【英文标题】:How do you drop a permanent table that has multiple prefixes on a remote server when RPC is disabled 【发布时间】:2021-12-13 14:15:27 【问题描述】:

在 SSMS v18 及更高版本中禁用 rpc 时,如何在远程服务器上删除具有多个前缀的永久表?

这是存储过程的一部分。

第一次尝试:

drop table if exists [remote_server_name].[remote_db_name].dbo.[test123]

错误信息:

对象名称“remote_server_name.remote_db_name.dbo.test123”包含的前缀数量超过了最大数量。最大值为 2。

在谷歌上搜索问题后,然后尝试以下方法;

第二次尝试:

EXECUTE [remote_server_name].[remote_db_name].[dbo].[sp_executesql] N'DROP TABLE [dbo].[test123]'

错误信息:

没有为 RPC 配置服务器“remote_server_name”。

第三次尝试:

drop table [remote_server_name].[remote_db_name].dbo.[test123]

错误信息:

对象名称“remote_server_name.remote_db_name.dbo.test123”包含的前缀数量超过了最大数量。最大值为 2。

【问题讨论】:

为什么不直接连接到其他服务器? 为什么你想通过链接服务器来做到这一点? 存储过程正在为不同的服务器重新编码,但正在删除的表还不能从“远程”服务器复制 你用什么技术来表示remote_server_name,究竟是什么?这是 OPENROWSET、链接服务器还是其他? 您使用的是什么版本的 SQL Server?这些都是本地实例吗?是否有任何 Azure SQL 或 Azure SQL 托管实例实例? 您正在尝试远程调用一个过程并且您无法更改链接服务器以支持 RPC(代表remote procedure call)?这是链接服务器配置中的简单是/否。您可以使用参数化的服务器名称动态调用sp_executesql,例如DECLARE @exec nvarchar(1000) = @server_name + N'.dbname.sys.sp_executesql'; EXEC @exec N'SELECT @@SERVERNAME, DB_NAME();'; 【参考方案1】:

很遗憾,您的整个问题的前提是错误的因为您不能将DROP TABLE 与非本地数据库一起使用。虽然文档中没有明确说明这一事实,但可以从 DROP TABLE 的语法仅支持这三种变体这一事实中推断出来:

DROP TABLE [ IF EXISTS ] database_name.schema_name.table_name;

DROP TABLE [ IF EXISTS ] schema_name.table_name;

DROP TABLE [ IF EXISTS ] table_name;

以上都不允许使用 SQL Server 名称。

奇怪的是,文档确实明确表示您不能在 Azure SQL 中使用 4 部分名称(这对某些人来说可能暗示本地(非 Azure SQL)确实 支持 4 部分名称,但事实上这两个版本的 SQL Server 都不支持 4 部分名称,因此 DROP TABLE 不能用于删除远程表:

https://docs.microsoft.com/en-us/sql/t-sql/statements/drop-table-transact-sql?view=sql-server-ver15

database_name 是当前数据库或database_nametempdb 并且object_name# 开头时,Azure SQL 数据库支持三部分名称格式 database_name.[schema_name].object_name。 Azure SQL 数据库不支持四部分名称。


但是,如果您使用的是链接服务器启用了 RPC,那么您可以使用EXEC AT。这种方法不适用于其他类型的远程服务器,例如OPENROWSET,也不适用于服务器选项中的“RPC: False”。

EXEC ( 'DROP TABLE dbName.schema.tableName;' ) AT [LinkedServerName];

否则,您无法从PROCEDURE 中直接删除远程服务器中的表。

一种 hack-ish 方法可能会起作用,您可以使用 xp_cmdshell(默认情况下也禁用)对任意 SQL Server 实例运行 sqlcmd.exe(nee osql.exe) - 尽管显然您需要超小心使用这种方法(您还需要可信安全 (SSPI) 工作,否则您需要在某处硬编码 DDL 特权用户的密码,这在生产系统中应避免使用)。

【讨论】:

以上是关于禁用 RPC 时如何在远程服务器上删除具有多个前缀的永久表的主要内容,如果未能解决你的问题,请参考以下文章

C ++中的远程过程调用(RPC):当端点被硬编码时,多个客户端可以监听一个服务器吗?

什么时候需要用rpc服务

GWT:客户端过程和 rpc 请求总是被多次调用,具有多个线程 id

如何将 C# 客户端 RPC 写入远程本机 C++ 服务器?

什么是RPC服务

XXL-RPC原理分析