Here is a procedure what I wrote
CREATE PROCEDURE dbo.ixRebuild @fillfactor int = 100, @Force bit = 0, @Schema varchar(255) = NULL, @Table varchar(255) = NULL, @PkOnly bit = 0
AS
/*
* ixRebuild
* Rebuild all indices in a database.
* Indices with >30% fragmentation are rebuilt.
* Indices with >6% fragmentation are just reorganised.
*
* The default fill factor is 100%.
*
* Required permissions are:
* GRANT VIEW DATABASE STATE TO <user>
* GRANT ALTER TO <user>
* GRANT EXEC ON ixRebuild TO <user>
*
* Created 17/9/08 by rwb.
*/
BEGIN
DECLARE @db int
DECLARE @tab varchar(256)
DECLARE @ix int
DECLARE @ixName varchar(256)
DECLARE @frag float
DECLARE @cmd varchar(1024)
DECLARE @type int
DECLARE c CURSOR FAST_FORWARD FOR
SELECT DISTINCT s.database_id, s.index_id, i.name,
Convert(float, s.avg_fragmentation_in_percent),
ss.name + '.' + t.name AS tableName,
i.type
FROM sys.dm_db_index_physical_stats(Db_Id(), NULL, NULL, NULL, NULL) s
INNER JOIN sys.indexes i ON s.object_id = i.object_id AND s.index_id = i.index_id
INNER JOIN sys.tables t ON i.object_id = t.object_id
INNER JOIN sys.schemas ss ON t.schema_id = ss.schema_id
WHERE (@Schema IS NULL OR ss.name = @Schema)
AND (@Table IS NULL OR t.name = @Table)
AND (@PkOnly = 0 OR i.is_primary_key = 1)
AND (
@Force = 1
OR (
avg_fragmentation_in_percent > 6
AND page_count > 100 -- rebuilding small indices does nothing
AND i.name IS NOT NULL -- for tables with no PK
)
)
-- DISTINCT because ys.dm_db_index_physical_stats
-- contains a row for each part of a partitioned index on a partitioned table.
OPEN c
FETCH NEXT FROM c INTO @db, @ix, @ixName, @frag, @tab, @type
WHILE @@Fetch_Status = 0
BEGIN
PRINT Db_Name( @db ) + ' / ' + @tab + ' / ' + @ixName + ' ' + Cast(@frag as varchar(16))
SET @cmd = ''
IF @frag < 10.0 AND @Force = 0
BEGIN
SET @cmd = 'ALTER INDEX ' + @ixName + ' ON ' + @tab + ' REORGANIZE'
END
ELSE
BEGIN
SET @cmd = 'ALTER INDEX ' + @ixName + ' ON ' + @tab +
CASE
WHEN @type IN (1, 2) THEN ' REBUILD WITH (FILLFACTOR = ' + Cast(@fillfactor AS varchar(4)) + ')'
ELSE ''
END
END
RAISERROR(@cmd, 0, 1) WITH NOWAIT;
EXEC (@cmd)
FETCH NEXT FROM c INTO @db, @ix, @ixName, @frag, @tab, @type
END
CLOSE c
DEALLOCATE c
END