sp_MSforeachdb: only include results from databases with results

前端 未结 2 1188
南方客
南方客 2020-12-03 16:04

I\'m running the below stored procedure sp_MSforeachdb with a simple command. My question is how to limit the result to show only the databases that have at lea

2条回答
  •  鱼传尺愫
    2020-12-03 16:35

    Well, first, stop using sp_MSforEachDb. Oh, the problems (if you want proof, see here).

    How about:

    DECLARE @cmd NVARCHAR(MAX) = N'', @sql NVARCHAR(MAX) = N'';
    
    SELECT @cmd += N'IF EXISTS (SELECT 1 FROM '
      + QUOTENAME(name) + '.sys.tables WHERE name = N''Tabs'')
      SET @sql += N''UNION ALL 
        SELECT ''''' + name + ''''',T.TabName
        FROM ' + QUOTENAME(name) + '.dbo.Tabs AS T
        WHERE EXISTS 
        (
          SELECT 1 FROM ' + QUOTENAME(name) + '.dbo.TabModules AS TM
            WHERE TM.TabID = T.TabID
            AND TM.mID IN -- this should probably be exists too
            ( 
              ...
            )
        )
    '''
    FROM sys.databases 
      WHERE state = 0 -- assume you only want online databases
      AND database_id > 4; -- assume you don't want system dbs
    
    EXEC sp_executesql @cmd, N'@sql NVARCHAR(MAX) OUTPUT', @sql OUTPUT;
    
    SET @sql = STUFF(@sql, 1, 10, '') + N' ORDER BY TabName;';   
    
    PRINT @sql; -- this will appear truncated, but trust me, it is not truncated
    -- EXEC sp_executesql @sql;
    

    If you really want some unknown, arbitrary number of separate resultsets, the change is simple.

    DECLARE @cmd NVARCHAR(MAX) = N'', @sql NVARCHAR(MAX) = N'';
    
    SELECT @cmd += N'IF EXISTS (SELECT 1 FROM '
      + QUOTENAME(name) + '.sys.tables WHERE name = N''Tabs'')
      SET @sql += N''SELECT ''''' + name + ''''',T.TabName
        FROM ' + QUOTENAME(name) + '.dbo.Tabs AS T
        WHERE EXISTS 
        (
          SELECT 1 FROM ' + QUOTENAME(name) + '.dbo.TabModules AS TM
            WHERE TM.TabID = T.TabID
            AND TM.mID IN -- this should probably be exists too
            ( 
              ...
            )
        )
     ORDER BY T.TabName;
     '';'
    FROM sys.databases 
      WHERE state = 0 -- assume you only want online databases
      --AND database_id > 4; -- assume you don't want system dbs
    
    EXEC sp_executesql @cmd, N'@sql NVARCHAR(MAX) OUTPUT', @sql OUTPUT;
    
    PRINT @sql; -- this will appear truncated, but trust me, it is not truncated
    -- EXEC sp_executesql @sql;
    

提交回复
热议问题