如何使用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;
你最好的朋友会帮你调试任何错误,但我假设你提供的声明是有效的。
我有一个代码 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;
你最好的朋友会帮你调试任何错误,但我假设你提供的声明是有效的。