2009-07-09 3 views
0

Als Teil einer Skriptprozedur versuche ich programmgesteuert aktualisieren Referenzen auf verknüpfte Server in gespeicherten Procs. Wir haben mehrere Referenzen wie folgt aus: -Programmgesteuertes Ersetzen von verknüpften Serververweisen durch lokale Datenbankverweise in SQL Server gespeicherten Procs?

SELECT foo, bar 
FROM [Server].[Database].dbo.[Table] 

Was ich möchte übersetzen: -

SELECT foo, bar 
FROM [Database].dbo.[Table] 

Ich möchte dies in einem ganz programmatisch tun ‚fire and forget‘ Skript über mehrere Datenbanken .

Die Idee, die ich gerade habe, ist die Verwendung von Metadaten, um Verweise auf verknüpfte Tabellen zu finden, den Text jedes Sp aus Metadaten erneut zu lesen, den Text jedes Sp anzupassen und jeden Block aktualisierten Textes in eine exec-Anweisung zu schieben em eins nach dem anderen.

Ich frage mich, ob das ein enormer Schmerz wird, aber hat jemand bessere Ideen? Ich bin offen für die Verwendung von Powershell, wenn das eine bessere Lösung bieten könnte.

Vielen Dank im Voraus!

+0

fyi: Die 'sqlserver *' -Tags wurden siteweit umbenannt. Bitte benutze 'sql-server' in Zukunft. –

+0

Ah danke. War mir nicht bewusst (war hier schon eine Weile nicht mehr ...!) – ljs

Antwort

1

Hoffentlich bin Verständnis ich die Fragen, sondern als Entfernen oder Ersetzen [Server], schlage ich vor, einen von zwei Ansätzen:

  • Option 1: Wählen Sie eine der SPs nicht ändern. Aktualisieren Sie stattdessen die verknüpfte Serverkonfiguration so, dass sie auf eine andere Datenbank verweist, sogar auf die lokale Box.

  • Option 2: Ändern Sie keines der SPs. Verwenden Sie stattdessen SQL Server Aliase. SQL Server-Aliase sind , die über das CliConfig-Dienstprogramm verwaltet werden, und werden schließlich in der -Registrierung gespeichert. So können sie manuell oder per .reg Skript angewendet werden. Grundsätzlich dechiffriert der SQL Server-Alias ​​ den Server (zusammen mit dem Port ), auf den verwiesen wird. Wenn Sie auf den Link Server Konfiguration aktualisieren, um die SQL Server Alias ​​anstelle einer bestimmten Server zu verweisen, können Sie Ihre Verfahren zu anderen Server (auch der lokale Server) zeigen, wann immer Sie möchten.

Ich hoffe, es hilft.

+0

Das Problem mit der Aktualisierung der verbundenen Server auf die lokale Box (was in diesem Fall notwendig ist) ist, dass es Probleme mit Loopback-verbundenen Servern gibt , hauptsächlich mit dem Schreiben von Daten in der gleichen Abfrage wie das Lesen vom Verbindungsserver, etwas, was ich tun muss. Aliase reparieren es nicht als SQL-Server nicht lästige Überprüfung Aliase für verbundene Server (afaik). – ljs

1

Ihre Herangehensweise ist die einfachste, ehrlich gesagt. Ich hatte ein ähnliches Problem Anfang des Jahres

  • Lesen sys.sql_modules
  • REPLACE den Verbindungsserver Text und CREATE -> ALTER
  • EXEC (@Result)
1

Hier ist ein Skript alle Procs/Funktionen/Ansichten zu finden, die Verbindungsserver auf einem SQL 2005-Instanz verweisen - vielleicht auch nützlich:

 
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 
1

Dies ist nicht eine gute Idee für eine Produktionsumgebung sein würde, aber wenn Sie eine Loopback-Verbindungsserver für dev Zwecke benötigen this für mich gearbeitet:

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'