Here is an example SQL to dump and recreate the index safely:
IF(select object_id from sys.indexes where [name] = 'IDX_RecordSubscription' and object_id = OBJECT_ID('[SystemSetup].[RecordSubscription]')) IS NOT NULL BEGIN DROP INDEX [SystemSetup].[RecordSubscription].IDX_RecordSubscription END GO CREATE UNIQUE INDEX IDX_RecordSubscription ON [SystemSetup].[RecordSubscription] ( Subscriber ASC, MenuItem ASC, RecordPrimaryKeyGuid ASC ) WITH ( PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = OFF ) ON [PRIMARY] GO
Here is the C # code that deflates this:
protected override string GetCreateIndexScript(string uniquePart, string indexName, string fullTableName, string columnsPart) { return $"IF(select object_id from sys.indexes where [name] = '{indexName}' and object_id = OBJECT_ID('{fullTableName}')) IS NOT NULL \r\n" + "BEGIN \r\n" + $" DROP INDEX {fullTableName}.{indexName} \r\n " + "END\r\n\r\n" + "GO\r\n\r\n" + $"CREATE {uniquePart} INDEX\r\n" + $"\t{indexName}\r\n" + "ON\r\n" + $"\t{fullTableName}\r\n" + "\t(\r\n" + $"\t\t{columnsPart}\r\n" + "\t)\r\n" + "\tWITH\r\n" + "\t(\r\n" + "\t\tPAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = OFF\r\n" + "\t) ON [PRIMARY] "; }
Here are some C # (which can be converted to SQL) to get the index schema:
const string selectStatement = "select " + " SCHEMAs.name + '.' + tabs.name as OBJECT_ID, " + " ind.name as INDEX_NAME, " + " indcol.index_id AS INDEX_ID, " + " indcol.key_ordinal AS COLUMN_ORDINAL, " + " col.name AS COLUMN_NAME, " + " ind.is_unique " + "from " + " sys.indexes ind " + "inner join " + " sys.index_columns indcol " + "on " + " ind.object_id = indcol.object_id and " + " ind.index_id = indcol.index_id " + "inner join " + " sys.columns col " + "on " + " col.object_id = indcol.object_id and " + " col.column_id = indcol.column_id " + "inner join " + " sys.tables tabs " + "on " + " tabs.object_id = ind.object_id " + "inner join " + " sys.schemas schemas " + "on " + " tabs.schema_id = schemas.schema_id " + "where " + " ind.type =2 and" + " tabs.name <> 'sysdiagrams' " + "order by " + " tabs.object_id, " + " indcol.index_id, " + " indcol.key_ordinal "; return DatabaseAdapter.Fill(selectStatement, null, null, null);
So basically, you are executing the last piece of code here, repeating the results (indexes and columns) and calling GetCreateIndexScript for each index returned. You can then safely execute each of the created statements to reset and recreate indexes.
The same approach can be used with TSQL or another language.