sql >> Databáze >  >> RDS >> Sqlserver

Kurzor SQL Server - procházet více servery a provádět dotaz

DECLARE @SN VARCHAR(20);

DECLARE C CURSOR LOCAL FAST_FORWARD
  FOR SELECT DISTINCT(SERVERNAME) FROM TABLE 
  where SERVERNAME NOT IN ('SRV1','SRV2','SRV3');

OPEN C;

FETCH NEXT FROM C INTO @SN;
WHILE (@@FETCH_STATUS = 0)
BEGIN 
    PRINT @SN;
    -- you could loop here for each database, if you'd define what that is
    SET @sql = N'SELECT * FROM ' + @SN + '.master.dbo.TABLE;';
    EXEC sys.sp_executesql @sql;
    FETCH NEXT FROM C INTO @SN;
END 
CLOSE C;
DEALLOCATE C;

Změny:

  1. Není důvod zde používat výchozí možnosti kurzoru – globální, aktualizovatelný, dynamický, rolovací atd. Pozadí .

  2. Jako zvyk / doporučený postup používejte sp_executesql a ne EXEC() . I když na tom v tomto případě nezáleží, v jiných to může vadit, takže bych raději vždy kódoval stejným způsobem. Pozadí .

  3. Také si prosím zvykněte ukončovat svá prohlášení středníkem. Nakonec budeš muset. Pozadí .

UPRAVIT

Nyní, když máme trochu více informací o vašich skutečných požadavcích, navrhuji tento kousek kódu. A podívejte, žádné kurzory (no, žádné explicitní deklarace kurzoru a veškeré lešení, které je s nimi)!

SET NOCOUNT ON;

DECLARE @dbs TABLE(SERVERNAME SYSNAME, DBNAME SYSNAME);

DECLARE @sql NVARCHAR(MAX) = N'';

-- first, let's get the databases on each server:

SELECT @sql += N'SELECT ''' + SERVERNAME + ''', name FROM '
 + QUOTENAME(SERVERNAME) + '.master.sys.databases
   WHERE database_id > 4 
   AND name NOT IN (N''somedb'',N''someotherdb'');' 
 FROM dbo.INSTALLATION 
   WHERE DATABASETYPE = 'MsSql' 
   AND SERVERNAME IN ('x');

INSERT @dbs EXEC sys.sp_executesql @sql;

SELECT @sql = N'';

-- now, build a command to run in each database context:

SELECT @sql += N'
  EXEC ' + QUOTENAME(SERVERNAME) + '.'
  + QUOTENAME(DBNAME) + '.sys.sp_executesql @sql;'
  FROM @dbs;

-- feel free to change the 3rd parameter here:

EXEC sys.sp_executesql @sql, N'@sql NVARCHAR(MAX)', 
  N'SELECT @@SERVERNAME, DB_NAME(), actual_columns FROM dbo.table_name;';

Toto selže, pokud název_tabulky neexistuje, takže možná budete mít ještě nějakou práci, pokud chcete usnadnit zpracování chyb. Ale tohle by vás mělo nastartovat.

Také si prosím uvědomte a důsledně používejte předponu schématu. Pozadí .




  1. Správné nastavení databáze připojení databáze database.yml pro jednovláknové aplikace Rails

  2. Chyba NodeJS Postgres getaddrinfo ENOTFOUND

  3. 4 způsoby, jak v Oracle najít řádky, které obsahují velká písmena

  4. Úroveň izolace SNAPSHOT