|
| 1 | +-- ============================================ |
| 2 | +-- Drop if exists (for clean redeploy) |
| 3 | +-- ============================================ |
| 4 | +IF OBJECT_ID('dbo.IndexOptimize', 'P') IS NOT NULL DROP PROCEDURE dbo.IndexOptimize; |
| 5 | +IF OBJECT_ID('dbo.DatabaseIntegrityCheck', 'P') IS NOT NULL DROP PROCEDURE dbo.DatabaseIntegrityCheck; |
| 6 | +IF OBJECT_ID('dbo.CommandExecute', 'P') IS NOT NULL DROP PROCEDURE dbo.CommandExecute; |
| 7 | +IF OBJECT_ID('dbo.CommandLog', 'U') IS NOT NULL DROP TABLE dbo.CommandLog; |
| 8 | +GO |
| 9 | + |
| 10 | +-- ============================================ |
| 11 | +-- CommandLog table |
| 12 | +-- ============================================ |
| 13 | +CREATE TABLE dbo.CommandLog ( |
| 14 | + ID INT IDENTITY PRIMARY KEY, |
| 15 | + DatabaseName SYSNAME NULL, |
| 16 | + SchemaName SYSNAME NULL, |
| 17 | + ObjectName SYSNAME NULL, |
| 18 | + ObjectType CHAR(2) NULL, |
| 19 | + IndexName SYSNAME NULL, |
| 20 | + IndexType TINYINT NULL, |
| 21 | + StatisticsName SYSNAME NULL, |
| 22 | + PartitionNumber INT NULL, |
| 23 | + ExtendedInfo XML NULL, |
| 24 | + Command NVARCHAR(MAX) NOT NULL, |
| 25 | + CommandType NVARCHAR(60) NOT NULL, |
| 26 | + StartTime DATETIME NOT NULL, |
| 27 | + EndTime DATETIME NOT NULL, |
| 28 | + ErrorNumber INT NOT NULL, |
| 29 | + ErrorMessage NVARCHAR(MAX) NULL |
| 30 | +); |
| 31 | +GO |
| 32 | + |
| 33 | +-- ============================================ |
| 34 | +-- CommandExecute stored procedure |
| 35 | +-- ============================================ |
| 36 | +CREATE PROCEDURE dbo.CommandExecute |
| 37 | + @Command NVARCHAR(MAX), |
| 38 | + @CommandType NVARCHAR(60), |
| 39 | + @DatabaseName SYSNAME = NULL, |
| 40 | + @SchemaName SYSNAME = NULL, |
| 41 | + @ObjectName SYSNAME = NULL, |
| 42 | + @ObjectType CHAR(2) = NULL, |
| 43 | + @IndexName SYSNAME = NULL, |
| 44 | + @IndexType TINYINT = NULL, |
| 45 | + @StatisticsName SYSNAME = NULL, |
| 46 | + @PartitionNumber INT = NULL, |
| 47 | + @ExtendedInfo XML = NULL |
| 48 | +AS |
| 49 | +BEGIN |
| 50 | + SET NOCOUNT ON; |
| 51 | + |
| 52 | + DECLARE @StartTime DATETIME = GETDATE(); |
| 53 | + DECLARE @ErrorNumber INT = 0; |
| 54 | + DECLARE @ErrorMessage NVARCHAR(MAX) = NULL; |
| 55 | + |
| 56 | + BEGIN TRY |
| 57 | + EXEC (@Command); |
| 58 | + END TRY |
| 59 | + BEGIN CATCH |
| 60 | + SET @ErrorNumber = ERROR_NUMBER(); |
| 61 | + SET @ErrorMessage = ERROR_MESSAGE(); |
| 62 | + END CATCH; |
| 63 | + |
| 64 | + INSERT INTO dbo.CommandLog ( |
| 65 | + DatabaseName, SchemaName, ObjectName, ObjectType, IndexName, IndexType, StatisticsName, |
| 66 | + PartitionNumber, ExtendedInfo, Command, CommandType, StartTime, EndTime, ErrorNumber, ErrorMessage |
| 67 | + ) |
| 68 | + VALUES ( |
| 69 | + @DatabaseName, @SchemaName, @ObjectName, @ObjectType, @IndexName, @IndexType, @StatisticsName, |
| 70 | + @PartitionNumber, @ExtendedInfo, @Command, @CommandType, @StartTime, GETDATE(), @ErrorNumber, @ErrorMessage |
| 71 | + ); |
| 72 | + |
| 73 | + IF @ErrorNumber <> 0 |
| 74 | + RAISERROR(@ErrorMessage, 16, 1); |
| 75 | +END |
| 76 | +GO |
| 77 | + |
| 78 | +-- ============================================ |
| 79 | +-- IndexOptimize stored procedure |
| 80 | +-- ============================================ |
| 81 | +CREATE PROCEDURE dbo.IndexOptimize |
| 82 | + @Databases NVARCHAR(MAX) = 'USER_DATABASES', |
| 83 | + @FragmentationMedium TINYINT = 30, |
| 84 | + @FragmentationHigh TINYINT = 70 |
| 85 | +AS |
| 86 | +BEGIN |
| 87 | + SET NOCOUNT ON; |
| 88 | + |
| 89 | + DECLARE @db SYSNAME; |
| 90 | + DECLARE db_cursor CURSOR FOR |
| 91 | + SELECT name FROM sys.databases |
| 92 | + WHERE (@Databases = 'USER_DATABASES' AND database_id > 4) |
| 93 | + OR name = @Databases; |
| 94 | + |
| 95 | + OPEN db_cursor; |
| 96 | + FETCH NEXT FROM db_cursor INTO @db; |
| 97 | + |
| 98 | + WHILE @@FETCH_STATUS = 0 |
| 99 | + BEGIN |
| 100 | + DECLARE @sql NVARCHAR(MAX) = N' |
| 101 | + USE [' + @db + ']; |
| 102 | +
|
| 103 | + DECLARE @schema SYSNAME, @table SYSNAME, @index SYSNAME; |
| 104 | + DECLARE @index_id INT, @frag FLOAT; |
| 105 | +
|
| 106 | + DECLARE c CURSOR FOR |
| 107 | + SELECT s.name, t.name, i.name, i.index_id, ips.avg_fragmentation_in_percent |
| 108 | + FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, ''LIMITED'') ips |
| 109 | + JOIN sys.indexes i ON i.object_id = ips.object_id AND i.index_id = ips.index_id |
| 110 | + JOIN sys.tables t ON t.object_id = ips.object_id |
| 111 | + JOIN sys.schemas s ON s.schema_id = t.schema_id |
| 112 | + WHERE ips.index_id > 0 AND ips.page_count > 100; |
| 113 | +
|
| 114 | + OPEN c; |
| 115 | + FETCH NEXT FROM c INTO @schema, @table, @index, @index_id, @frag; |
| 116 | +
|
| 117 | + WHILE @@FETCH_STATUS = 0 |
| 118 | + BEGIN |
| 119 | + DECLARE @cmd NVARCHAR(MAX); |
| 120 | + SET @cmd = ''ALTER INDEX ['' + @index + ''] ON ['' + @schema + ''].['' + @table + ''] ''; |
| 121 | +
|
| 122 | + IF @frag >= ' + CAST(@FragmentationHigh AS NVARCHAR) + ' |
| 123 | + SET @cmd += ''REBUILD''; |
| 124 | + ELSE IF @frag >= ' + CAST(@FragmentationMedium AS NVARCHAR) + ' |
| 125 | + SET @cmd += ''REORGANIZE''; |
| 126 | + ELSE |
| 127 | + SET @cmd = NULL; |
| 128 | +
|
| 129 | + IF @cmd IS NOT NULL |
| 130 | + EXEC dbo.CommandExecute @Command = @cmd, |
| 131 | + @CommandType = ''ALTER INDEX'', |
| 132 | + @DatabaseName = ''' + @db + ''', |
| 133 | + @SchemaName = @schema, |
| 134 | + @ObjectName = @table, |
| 135 | + @ObjectType = ''U'', |
| 136 | + @IndexName = @index; |
| 137 | +
|
| 138 | + FETCH NEXT FROM c INTO @schema, @table, @index, @index_id, @frag; |
| 139 | + END; |
| 140 | +
|
| 141 | + CLOSE c; |
| 142 | + DEALLOCATE c; |
| 143 | + '; |
| 144 | + |
| 145 | + EXEC sp_executesql @sql; |
| 146 | + FETCH NEXT FROM db_cursor INTO @db; |
| 147 | + END; |
| 148 | + |
| 149 | + CLOSE db_cursor; |
| 150 | + DEALLOCATE db_cursor; |
| 151 | +END |
| 152 | +GO |
| 153 | + |
| 154 | +-- ============================================ |
| 155 | +-- DatabaseIntegrityCheck stored procedure |
| 156 | +-- ============================================ |
| 157 | +CREATE PROCEDURE dbo.DatabaseIntegrityCheck |
| 158 | + @Databases NVARCHAR(MAX) = 'USER_DATABASES' |
| 159 | +AS |
| 160 | +BEGIN |
| 161 | + SET NOCOUNT ON; |
| 162 | + |
| 163 | + DECLARE @db SYSNAME; |
| 164 | + DECLARE db_cursor CURSOR FOR |
| 165 | + SELECT name FROM sys.databases |
| 166 | + WHERE (@Databases = 'USER_DATABASES' AND database_id > 4) |
| 167 | + OR name = @Databases; |
| 168 | + |
| 169 | + OPEN db_cursor; |
| 170 | + FETCH NEXT FROM db_cursor INTO @db; |
| 171 | + |
| 172 | + WHILE @@FETCH_STATUS = 0 |
| 173 | + BEGIN |
| 174 | + DECLARE @cmd NVARCHAR(MAX); |
| 175 | + SET @cmd = 'DBCC CHECKDB([' + @db + ']) WITH NO_INFOMSGS, ALL_ERRORMSGS'; |
| 176 | + |
| 177 | + EXEC dbo.CommandExecute |
| 178 | + @Command = @cmd, |
| 179 | + @CommandType = 'DBCC CHECKDB', |
| 180 | + @DatabaseName = @db; |
| 181 | + |
| 182 | + FETCH NEXT FROM db_cursor INTO @db; |
| 183 | + END |
| 184 | + |
| 185 | + CLOSE db_cursor; |
| 186 | + DEALLOCATE db_cursor; |
| 187 | +END |
| 188 | +GO |
| 189 | + |
| 190 | +-- ============================================ |
| 191 | +-- Purge command log stored procedure |
| 192 | +-- ============================================ |
| 193 | +CREATE OR ALTER PROCEDURE dbo.sp_purge_commandlog |
| 194 | + @DaysToKeep INT = 30 |
| 195 | +AS |
| 196 | +BEGIN |
| 197 | + SET NOCOUNT ON; |
| 198 | + |
| 199 | + DECLARE @DeleteBefore DATETIME = DATEADD(DAY, -@DaysToKeep, GETDATE()); |
| 200 | + |
| 201 | + DELETE FROM dbo.CommandLog |
| 202 | + WHERE StartTime < @DeleteBefore; |
| 203 | +END |
| 204 | +GO |
0 commit comments