-- Gets Stats Date and Fragmentation Statistics where fragmentation is > 7%
use EnVisage
go

IF EXISTS ( SELECT  * FROM    sys.objects WHERE   object_id = OBJECT_ID(N'sp_DBMaintenance')    AND type IN ( N'P', N'PC' ) ) 
  drop procedure [dbo].[sp_DBMaintenance]
go

CREATE PROCEDURE [dbo].[sp_DBMaintenance] AS
begin 
truncate table supt_tbl_DbMaintenanceCommands
DBCC CHECKIDENT (supt_tbl_DbMaintenanceCommands, reseed, 34)

SELECT [Object Name] = object_name(ps.object_id), 
	   [Index Name] = i.name, 
	   [Fragmentation %] = cast(avg_fragmentation_in_percent as varchar(15)), 
	   [Stats Updated] = STATS_DATE(i.object_id, i.index_id)
  FROM sys.dm_db_index_physical_stats(db_id(), null, null, null, 'sampled')  AS ps
  JOIN sys.indexes AS i 
	ON ps.[object_id] = i.[object_id] 
   AND ps.index_id = i.index_id 
 WHERE (ps.avg_fragmentation_in_percent >= 7
	OR  ps.avg_page_space_used_in_percent < 75)
   AND  ps.page_count > 8
   AND  ps.index_id > 0


-- Update Statistics (previous update date is listed after each statement generated)
insert into supt_tbl_DbMaintenanceCommands (command,executed)
select 'Update Statistics [' + schema_name(o.schema_id) + '].[' + o.name + '] [' + i.name + '] WITH SAMPLE 100 Percent;' ,0
  from sys.objects o
  join sys.indexes i
	on o.object_id = i.object_id
   and OBJECTPROPERTY(o.object_id, N'IsUserTable') = 1
   and i.index_id > 0
 order by isnull(convert(char(10), STATS_DATE(o.object_id, i.index_id), 101), 'N/A') asc

 insert into supt_tbl_DbMaintenanceCommands (command,executed)
-- reorganize indexes (fragmentation will show after each statement generated)
SELECT 'alter index [' + i.name + '] on [' + object_name(ps.object_id) + '] reorganize -- ' + cast(avg_fragmentation_in_percent as varchar(15)),0
  FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL, NULL, 'LIMITED')  AS ps
  JOIN sys.indexes AS i 
	ON ps.[object_id] = i.[object_id] 
   AND ps.index_id = i.index_id 
   AND i.type_desc <> 'HEAP'
 where avg_fragmentation_in_percent > 7


insert into supt_tbl_DbMaintenanceCommands (command,executed)
-- rebuild indexes (fragmentation will show after each statement generated)
SELECT 'alter index [' + i.name + '] on [' + object_name(ps.object_id) + '] rebuild -- ' + cast(avg_fragmentation_in_percent as varchar(15)),0
  FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL, NULL, 'LIMITED')  AS ps
  JOIN sys.indexes AS i 
	ON ps.[object_id] = i.[object_id] 
   AND ps.index_id = i.index_id 
   AND i.type_desc <> 'HEAP'
 where avg_fragmentation_in_percent > 7



insert into supt_tbl_DbMaintenanceCommands (command,executed)
-- find indexes with 0% fill factor and rebuild with 90%
select 'alter index [' + b.name + '] on [' + schema_name(a.schema_id) + '].[' + a.name + '] rebuild with (online = off' + case b.fill_factor when 0 then ', fillfactor = 90' else '' end + ');' ,0
  from sys.objects a
  join sys.indexes b
	on a.object_id = b.object_id
 where a.type = 'u'
   and a.name <> 'dtproperties'
   and b.fill_factor = 0
   and b.name is not NULL



   declare @max int =0

   select @max=max(id) from supt_tbl_DbMaintenanceCommands where isnull(executed,0)  = 0 
   declare @on int=1;

   while (@on <= @max)
   begin
   declare @cmd nvarchar(max)
   select @cmd=command from supt_tbl_DbMaintenanceCommands where id = @on
   if not isnull(@cmd,'') = ''
   begin
   declare @results nvarchar(max)
   declare @cd bit=1
   BEGIN TRY

	EXECUTE sp_executesql @cmd
	set @results='success';
END TRY
BEGIN CATCH
	SELECT @results= ERROR_MESSAGE(),@cd=null
	
END CATCH
	update supt_tbl_DbMaintenanceCommands set Results=@results, executed=@cd where id=@on
		
		
   end

   set @on=@on+1
   end 
   end