在SQL server存储过程中以编程方式将链接服务器引用替换为本地数据库引用?

在SQL server存储过程中以编程方式将链接服务器引用替换为本地数据库引用?,sql,sql-server,metadata,Sql,Sql Server,Metadata,作为脚本化过程的一部分,我试图以编程方式更新对存储过程中链接服务器的引用。我们有几个类似的参考文献:- SELECT foo, bar FROM [Server].[Database].dbo.[Table] 我想翻译成:- SELECT foo, bar FROM [Database].dbo.[Table] 我希望在跨多个数据库的“fire-and-forget”脚本中完全以编程方式实现这一点 我现在的想法是使用元数据查找链接表的引用,再次从元数据中读取每个sp的文本,调整每个sp的文本

作为脚本化过程的一部分,我试图以编程方式更新对存储过程中链接服务器的引用。我们有几个类似的参考文献:-

SELECT foo, bar
FROM [Server].[Database].dbo.[Table]
我想翻译成:-

SELECT foo, bar
FROM [Database].dbo.[Table]
我希望在跨多个数据库的“fire-and-forget”脚本中完全以编程方式实现这一点

我现在的想法是使用元数据查找链接表的引用,再次从元数据中读取每个sp的文本,调整每个sp的文本,然后将每个更新的文本块推入exec语句中,逐个重建它们

我想知道这是否会是一个巨大的痛苦,但是,有没有人有更好的想法?如果能够提供更好的解决方案,我愿意使用powershell


提前谢谢

希望我能理解这些问题,但我建议采用以下两种方法之一,而不是删除或更换[Server]:

  • 选项1:不要更改任何 SPs。相反,请更新链接的 点a的服务器配置 不同的数据库,甚至本地 盒子

  • 选项2:不要更改任何 SPs。相反,请开始使用SQL Server 别名。SQL Server别名是 通过CliConfig实用程序和 最终存储在 登记处。因此,它们可以被应用 手动或通过.reg脚本。 基本上,SQL Server别名 解密服务器(以及 正在引用的端口。如果 更新链接服务器 配置以引用SQL 服务器别名,而不是特定的 服务器,您可以指向您的程序 无论何时,都可以连接到不同的服务器(甚至本地服务器) 我想要


我希望它能有所帮助。

希望我能理解这些问题,但我建议采用以下两种方法之一,而不是删除或替换[Server]:

  • 选项1:不要更改任何 SPs。相反,请更新链接的 点a的服务器配置 不同的数据库,甚至本地 盒子

  • 选项2:不要更改任何 SPs。相反,请开始使用SQL Server 别名。SQL Server别名是 通过CliConfig实用程序和 最终存储在 登记处。因此,它们可以被应用 手动或通过.reg脚本。 基本上,SQL Server别名 解密服务器(以及 正在引用的端口。如果 更新链接服务器 配置以引用SQL 服务器别名,而不是特定的 服务器,您可以指向您的程序 无论何时,都可以连接到不同的服务器(甚至本地服务器) 我想要


我希望这会有帮助。

坦白说,你的方法是最简单的。今年早些时候我也遇到过类似的问题

  • 读取sys.sql\u模块
  • 替换链接的服务器文本并创建->更改
  • EXEC(@Result)

坦白说,你的方法是最简单的。今年早些时候我也遇到过类似的问题

  • 读取sys.sql\u模块
  • 替换链接的服务器文本并创建->更改
  • EXEC(@Result)

以下是一个脚本,用于查找引用SQL 2005实例上链接服务器的所有过程/函数/视图-可能也很有用:

USE master GO SET NOCOUNT ON; -------------------------------------------------------------------- -- Test linked server connections -------------------------------------------------------------------- BEGIN TRY DROP TABLE #Svrs; END TRY BEGIN CATCH END CATCH; CREATE TABLE #Svrs ( [Server] nvarchar(max), [CanConnectAsDefault] bit ); DECLARE @ServerName nvarchar(max), @RetVal int; DECLARE Svrs CURSOR FAST_FORWARD READ_ONLY FOR SELECT ServerName = S.name FROM sys.servers S; OPEN Svrs; FETCH NEXT FROM Svrs INTO @ServerName; WHILE @@FETCH_STATUS = 0 BEGIN BEGIN TRY EXEC @RetVal = sys.sp_testlinkedserver @ServerName; END TRY BEGIN CATCH SET @RetVal = sign(@@error); END CATCH; INSERT INTO #Svrs SELECT @ServerName , CASE WHEN @RetVal = 0 THEN 1 ELSE 0 END; FETCH NEXT FROM Svrs INTO @ServerName; END; CLOSE Svrs; DEALLOCATE Svrs; SELECT * FROM #Svrs DROP TABLE #Svrs; GO -------------------------------------------------------------------- -- Report linked server references -------------------------------------------------------------------- BEGIN TRY DROP TABLE #Refs; END TRY BEGIN CATCH END CATCH; CREATE TABLE #Refs ( [Server] nvarchar(max), [Database] nvarchar(max), [Schema] nvarchar(max), [Object] nvarchar(max), [Type] nvarchar(max) ); DECLARE @DatabaseName nvarchar(max), @ServerName nvarchar(max), @SQL nvarchar(max); DECLARE Refs CURSOR FAST_FORWARD READ_ONLY FOR SELECT DatabaseName = D.name , ServerName = S.name -- , ServerProvider = S.provider -- , ServerSource = S.data_source FROM sys.databases D CROSS JOIN sys.servers S WHERE D.name NOT IN ('master', 'tempdb', 'model', 'msdb', 'ReportServer', 'ReportServerTempDB'); OPEN Refs; FETCH NEXT FROM Refs INTO @DatabaseName, @ServerName; WHILE @@FETCH_STATUS = 0 BEGIN SET @SQL = 'USE [' + @DatabaseName + ']; INSERT INTO #Refs SELECT DISTINCT ''' + @ServerName + ''', ''' + @DatabaseName + ''', S.[name], O.[name], O.type_desc FROM syscomments C INNER JOIN sys.objects O ON C.id = O.[object_id] LEFT JOIN sys.schemas S ON S.[schema_id] = O.[schema_id] WHERE C.[TEXT] LIKE ''%[ ,~[( '''']' + @ServerName + '[ .,~])'''' ]%'' ESCAPE ''~'';' PRINT 'Looking for ' + @ServerName + ' refs in ' + @DatabaseName -- + ': ' + @SQL; EXEC sp_executesql @SQL; FETCH NEXT FROM Refs INTO @DatabaseName, @ServerName; END CLOSE Refs; DEALLOCATE Refs; SELECT * FROM #Refs DROP TABLE #Refs; GO -------------------------------------------------------------------- SET NOCOUNT OFF; GO 使用主机 去 不计数; -------------------------------------------------------------------- --测试链接的服务器连接 -------------------------------------------------------------------- 开始尝试放下桌子#Svrs;结束尝试开始捕捉结束捕捉; 创建表#SVR ( [服务器]nvarchar(最大值), [CanConnectAsDefault]位 ); 声明@ServerName-nvarchar(max),@RetVal-int; 声明Svrs光标快进只读 对于 选择ServerName=S.name 从sys.S; 开放SVR; 从Svrs获取下一个到@ServerName; 而@@FETCH\u STATUS=0 开始 开始尝试 EXEC@RetVal=sys.sp_testlinkedserver@ServerName; 结束尝试 开始捕捉 设置@RetVal=符号(@@error); 末端捕捉; 插入到#Svrs中 选择@ServerName ,如果@RetVal=0,则为1,否则为0结束; 从Svrs获取下一个到@ServerName; 结束; 关闭SVR; 取消分配SVR; 从#Svrs中选择* 升降台#Svrs; 去 -------------------------------------------------------------------- --报表链接服务器引用 -------------------------------------------------------------------- 开始尝试放置表格#参考;结束尝试开始捕捉结束捕捉; 创建表#参考 ( [服务器]nvarchar(最大值), [数据库]nvarchar(最大值), [Schema]nvarchar(最大值), [对象]nvarchar(最大值), [类型]nvarchar(最大值) ); 声明@DatabaseName-nvarchar(max)、@ServerName-nvarchar(max)、@SQL-nvarchar(max); 声明引用光标快进只读 对于 选择DatabaseName=D.name ,ServerName=S.name --,ServerProvider=S.provider --,ServerSource=S.data\u source 从sys.D数据库 交叉连接系统服务器 其中D.name不在('master','tempdb','model','msdb','ReportServer','ReportServerTempDB'); 开放参考文献; 从Refs获取下一个到@DatabaseName、@ServerName; 而@@FETCH\u STATUS=0 开始 SET@SQL='使用['+@DatabaseName+']; 插入#参考文献 选择不同的“”++@ServerName++“”、“”++@DatabaseName++“”、S.[name]、O.[name]、O.type_desc 来自sysc C.id=O上的内部联接sys.objects[object\u id] 左连接S.[schema\u id]=O.[schema\u id]上的sys.schemas 其中,C.[文本]类似于“%[,~[(“”“”])+@ServerName+”[,~])“']%'”转义“~”;” 在“++@DatabaseName-->”中打印“查找“++@ServerName+”引用”:“++@SQL; EXEC sp_executesql@SQL; 从Refs获取下一个到@DatabaseName、@ServerName; 结束 密切参考; 取消分配引用; 从#参考中选择* 升降台#参考; 去 -------------------------------------------------------------------- 不计数; 去
下面是一个查找所有进程的脚本
EXEC sp_addlinkedserver @server = N'name_for_linked_server',
    @srvproduct = N' ',
    @provider = N'SQLNCLI', 
    @datasrc = N'name_of_my_sqlserver_instance', 
    @catalog = N'name_of_database'