sql >> Database teknologi >  >> RDS >> Sqlserver

SQL Server-markør - loop gennem flere servere og udfør forespørgsel

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;

Ændringer:

  1. Der er ingen grund til at bruge standardmarkørindstillingerne her - global, opdaterbar, dynamisk, scrollbar osv. Baggrund .

  2. Som en vane/best practice skal du bruge sp_executesql og ikke EXEC() . Selvom det ikke betyder noget i dette tilfælde, kan det betyde noget i andre, så jeg foretrækker altid at kode på samme måde. Baggrund .

  3. Venligst væn dig også til at afslutte dine udsagn med semikolon. Det bliver du nødt til til sidst. Baggrund .

REDIGER

Nu hvor vi har lidt mere information om dine faktiske krav, foreslår jeg denne kodebit. Åh, og se, ingen markører (nå, ingen eksplicit markørerklæringer og alle de stilladser, der følger med dem)!

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;';

Dette vil mislykkes, hvis tabelnavn ikke eksisterer, så du har muligvis stadig noget arbejde at gøre, hvis du vil lette fejlhåndteringen. Men dette burde få dig i gang.

Vær også bevidst om og brug konsekvent skemapræfikset. Baggrund .




  1. Vælg flere feltduplikater fra MySQL-databasen

  2. MySQL - VÆLG, JOIN

  3. SQL - Opdel enkelt kolonne i flere kolonner

  4. MySQL's alternativ til T-SQL's MED BÅND