This procedure is used in the Database Maintenance Job - Rock Manual - Rock Admin Hero Guide - Care and Feeding of Rock

This stored procedure rebuilds the database indexes. The enhancement corrects the procedure to allow for using the @CommandOption parameter and corrects a bug by resetting the value at the end of the cursor to generate the correct syntax.


/****** Object: StoredProcedure [dbo].[spDbaRebuildIndexes] Script Date: 5/27/2026 6:14:04 PM ******/

SET ANSI_NULLS ON

GO

SET QUOTED_IDENTIFIER ON

GO

/*

<doc>

 <summary>

   This stored procedure rebuilds the database indexes.

 </summary>

 <returns>

 </returns>

 <param name='PageCountLimit' datatype='int'>The number of page counts the index must have in order to be considered for re-indexing (default 100).</param>

 <param name='MinFragmentation' datatype='int'>The minimum amount of fragmentation a index must have to be considered for re-indexing (default 10).</param>

 <param name='MinFragmentationRebuild' datatype='int'>The minimum amount of fragmentation a index must have to be considered for a full rebuild. Otherwise a reorganize will be done. (default 30).</param>

 <remarks>

  20260210 JLM Modified @CommandOption to be reset after it is created for each index. Line 91 SET @CommandOption = 'FILLFACTOR = 80';

 </remarks>

 <code>

  EXEC [dbo].[spDbaRebuildIndexes]

  EXEC [dbo].[spDbaRebuildIndexes] default, default, default, 1

  EXEC [dbo].[spDbaRebuildIndexes] default, 0, 0, 1

 </code>

</doc>

*/

ALTER PROCEDURE [dbo].[spDbaRebuildIndexes]

   @PageCountLimit int = 100

 , @MinFragmentation int = 10

 , @MinFragmentationRebuild int = 30

 , @UseONLINEIndexRebuild bit = 0

 WITH RECOMPILE

AS

BEGIN

DECLARE @SchemaName AS varchar(100);

DECLARE @TableName AS varchar(100);

DECLARE @IndexName AS varchar(100);

DECLARE @IndexType AS varchar(100);

DECLARE @FragmentationPercent AS varchar(100);

DECLARE @PageCount AS varchar(100);

DECLARE @MaintenanceCursor AS CURSOR;

DECLARE @CommandOption varchar(100) = 'FILLFACTOR = 80';

DECLARE @SqlCommand AS nvarchar(2000);

SET @MaintenanceCursor = CURSOR FOR

   SELECT

    dbschemas.[name] as 'Schema',

    dbtables.[name] as 'Table',

    dbindexes.[name] as 'Index',

    dbindexes.[type_desc] as 'IndexType',

    CONVERT(INT, indexstats.avg_fragmentation_in_percent),

    indexstats.page_count

   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 indexstats.page_count > @PageCountLimit

    AND indexstats.avg_fragmentation_in_percent > @MinFragmentation

   ORDER BY

    indexstats.avg_fragmentation_in_percent DESC

OPEN @MaintenanceCursor;

FETCH NEXT FROM @MaintenanceCursor INTO @SchemaName, @TableName, @IndexName, @IndexType, @FragmentationPercent, @PageCount;

WHILE @@FETCH_STATUS = 0

BEGIN

 IF (@FragmentationPercent > @MinFragmentationRebuild)

 BEGIN

  IF ( @UseONLINEIndexRebuild = 1 AND @IndexType NOT IN ('SPATIAL','XML') )

  BEGIN

   SELECT @CommandOption = @CommandOption + ', ONLINE = ON';

  END

  SET @SqlCommand = N'ALTER INDEX [' + @IndexName + N'] ON [' + @SchemaName + N'].[' + @TableName + '] REBUILD WITH (' + @CommandOption + ')';

 END

 ELSE BEGIN

  SET @SqlCommand = N'ALTER INDEX [' + @IndexName + N'] ON [' + @SchemaName + N'].[' + @TableName + '] REORGANIZE';

 END

 PRINT @SqlCommand;

 EXECUTE sp_executeSQL @SqlCommand;

 FETCH NEXT FROM @MaintenanceCursor INTO @SchemaName, @TableName, @IndexName, @IndexType, @FragmentationPercent, @PageCount;

 SET @CommandOption = 'FILLFACTOR = 80';

END

CLOSE @MaintenanceCursor;

DEALLOCATE @MaintenanceCursor;

END