sql >> データベース >  >> RDS >> Sqlserver

SQLServerカーソル-複数のサーバーをループしてクエリを実行します

    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. 表の値の連続発生数をカウントします

    2. SQL ServerのLIMITとOFFSETに相当しますか?

    3. XXXによる並べ替えASCまたはDESCによる並べ替え、動的な順序付け、mysql ..

    4. PostgreSQLの数値の前にプラス/マイナス記号を付ける