Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Курсор на SQL Server - преминаване през множество сървъри и изпълнение на заявка

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;

Промени:

  1. Няма причина да използвате опциите на курсора по подразбиране тук - глобален, обновяем, динамичен, превъртащ се и т.н. Фон .

  2. Като навик/най-добра практика използвайте sp_executesql а не EXEC() . Въпреки че няма особено значение в този случай, може да има значение в други, така че бих предпочел винаги да кодирам по един и същи начин. История .

  3. Също така, моля, придобийте навика да завършвате изявленията си с точка и запетая. Ще трябва, в крайна сметка. Фон .

РЕДАКТИРАНЕ

Сега, след като имаме малко повече информация за действителните ви изисквания, предлагам този код. О, вижте, няма курсори (е, няма изрично декларации на курсора и цялото скеле, което идва с тях)!

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

Това ще се провали, ако table_name не съществува, така че все още може да имате работа, ако искате да улесните обработката на грешки. Но това трябва да ви помогне да започнете.

Също така, моля, имайте предвид и използвайте последователно префикса на схемата. История .




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL Server ROWCOUNT_BIG()

  2. Инструкцията UPDATE е в конфликт с ограничението REFERENCE - SQL Server / TSQL урок, част 76

  3. Свързване на python 3.3 към microsoft sql сървър 2008

  4. Архивиране на SQL Server 2017 -3

  5. Не може да се предаде COM обект от тип „System.__ComObject“ към тип интерфейс „Microsoft.VisualStudio.OLE.Interop.IServiceProvider“