如何使用sp_MSforeachdb

How to use sp_MSforeachdb

我有一个代码 returns 所有碎片百分比大于 30

的索引

我希望此代码 运行 通过我所有的数据库并将结果集添加到 table 我调用了 IndexesToRebuild

有没有一种方法可以在所有数据库中使用 sp_MSforeachdb 到 运行 此查询并将结果集插入 IndexesToRebuild table

这是我目前的代码

if(not exists(select 1 from Utility..dtlIndexesToRebuild))
    begin




        insert into utility..dtlIndexesToRebuild

        select
                    DB_NAME(),
                    dbschemas.[name], 
                    dbtables.[name], 
                    dbindexes.[name],
                    indexstats.avg_fragmentation_in_percent         

        from 
                    sys.dm_db_index_physical_stats (DB_ID(), null, null, null, null) as indexstats
                    inner join sys.tables dbtables on dbtables.[object_id] = indexstats.[object_id]
                    inner join sys.schemas dbschemas on dbtables.[schema_id] = dbschemas.[schema_id]
                    inner join sys.indexes as dbindexes on dbindexes.[object_id] = indexstats.[object_id]
                    and indexstats.index_id = dbindexes.index_id

        where   
                    indexstats.database_id = DB_ID()
                    and avg_fragmentation_in_percent > 30

    end

sp_msforeachdb 有一些 "features"。对于像这样简单的事情,简单地利用一些动态 SQL:

可能会更容易
USE master;
GO

DECLARE @SQL nvarchar(MAX),
        @CRLF nchar(2) = NCHAR(13) + NCHAR(10);

SET @SQL = STUFF((SELECT @CRLF + @CRLF +
                         N'USE ' + QUOTENAME([name]) + N';' + @CRLF +
                         N'INSERT INTO utility.dbo.dtlIndexesToRebuild (DatabaseName, SchemaName, TableName, IndexName, Fragmentation)' + @CRLF + --Guessed names of your columns
                         N'SELECT DB_NAME(),' + @CRLF + 
                         N'       dbschemas.[name],' + @CRLF + 
                         N'       dbtables.[name],' + @CRLF + 
                         N'       dbindexes.[name],' + @CRLF + 
                         N'       indexstats.avg_fragmentation_in_percent' + @CRLF + 
                         N'FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, NULL) indexstats' + @CRLF + 
                         N'     INNER JOIN sys.tables dbtables ON dbtables.[object_id] = indexstats.[object_id]' + @CRLF + 
                         N'     INNER JOIN sys.schemas dbschemas ON dbtables.[schema_id] = dbschemas.[schema_id]' + @CRLF + 
                         N'     INNER JOIN sys.indexes dbindexes ON dbindexes.[object_id] = indexstats.[object_id]' + @CRLF + 
                         N'                                     AND indexstats.index_id = dbindexes.index_id' + @CRLF + 
                         N'WHERE indexstats.database_id = DB_ID()' + @CRLF + 
                         N'  AND avg_fragmentation_in_percent > 30;'
                  FROM sys.databases d
                  WHERE d.database_id > 4
                    --AND d.[name] != N'utility' --Don't know if you want to skip this
                  FOR XML PATH(N''),TYPE).value('.','nvarchar(MAX)'),1,4,N'');

--PRINT @SQL; --Your best friend. Use SELECT for over 4,000 characters.

EXEC sys.sp_executesql @SQL;

你最好的朋友会帮你调试任何错误,但我假设你提供的声明是有效的。