作为脚本程序的一部分,我正在尝试以编程方式更新对存储过程中链接服务器的引用。我们有几个像这样的引用: -
SELECT foo, bar
FROM [Server].[Database].dbo.[Table]
我想将其翻译成: -
SELECT foo, bar
FROM [Database].dbo.[Table]
我想在几个数据库的“fire and forget”脚本中完全以编程方式完成此操作。
我现在的想法是使用元数据来查找对链接表的引用,再次从元数据中读取每个sp的文本,调整每个sp的文本,然后将每个更新文本块推送到exec语句中以重建它们一个接一个。
我确实怀疑这是否会是一种巨大的痛苦,所以有没有更好的想法?如果可以提供更好的解决方案,我愿意使用PowerShell。
提前致谢!
答案 0 :(得分:1)
希望我理解这些问题,但不是删除或替换[Server],我建议采用以下两种方法之一:
选项1:不要改变任何一个 的SP。而是,更新链接 服务器配置指向a 不同的数据库,甚至是本地的 框。
选项2:不要改变任何一个 的SP。相反,开始使用SQL Server 别名。 SQL Server别名是 通过CliConfig实用程序进行管理 最终存储在 注册表中。因此,它们可以应用 手动或通过.reg脚本。 基本上,SQL Server别名 解密服务器(以及 正在引用的端口)。如果 您更新链接服务器 配置引用SQL 服务器别名而不是特定的 服务器,你可以指出你的程序 每当你到不同的服务器(甚至本地服务器) 想。
我希望它有所帮助。
答案 1 :(得分:1)
坦白说,你的方法最简单。我今年早些时候遇到了类似的问题
答案 2 :(得分:1)
这是一个脚本,用于查找在SQL 2005实例上引用链接服务器的所有proc / functions /视图 - 也可能有用:
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
答案 3 :(得分:1)
这对于生产环境来说不是一个好主意,但如果您需要一个用于开发目的的环回链接服务器this为我工作:
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'