Modification of Generate Index Scripts using Stored Procedure to also handle SQL Server Spatial Indexes.
Haven't tested this on GEOGRAPHY
indices, use at your own risk.
Modification of Generate Index Scripts using Stored Procedure to also handle SQL Server Spatial Indexes.
Haven't tested this on GEOGRAPHY
indices, use at your own risk.
IF OBJECT_ID('ScriptCreateDropIndexes_SP', 'P') IS NOT NULL | |
DROP PROC ScriptCreateDropIndexes_SP | |
GO | |
CREATE PROCEDURE ScriptCreateDropIndexes_SP | |
@TableName sysname , | |
@SchemaName sysname = 'dbo' , | |
@SORT_IN_TEMPDB VARCHAR(3) = 'OFF' , | |
@DROP_EXISTING VARCHAR(3) = 'OFF' , | |
@STATISTICS_NORECOMPUTE VARCHAR(3) = 'OFF' , | |
@ONLINE VARCHAR(3) = 'OFF' | |
AS /* | |
FROM: https://gallery.technet.microsoft.com/scriptcenter/Generate-Index-using-5d8a8895 | |
Modified to include sys.indices.type = 4 (spatial) | |
Parameters | |
@Schemaname - SchemaName to which the table belongs to. Default value 'dbo'. | |
@Tablename - TableName for which the Indexes need to be scripted. | |
@SORT_IN_TEMPDB - Runtime value for SORT_IN_TEMPDB option in create index. | |
Valid Values ON \ OFF. Default = 'OFF' | |
@DROP_EXISTING - Runtime value for DROP_EXISTING option in create index. | |
Valid Values ON \ OFF. Default = 'OFF' | |
@STATISTICS_NORECOMPUTE - Runtime value for STATISTICS_NORECOMPUTE option in create index. | |
Valid Values ON \ OFF. Default = 'OFF' | |
@ONLINE - Runtime value for ONLINE option in create index. | |
Valid Values ON \ OFF. Default = 'OFF' | |
*/ | |
SET NOCOUNT ON | |
IF @SORT_IN_TEMPDB NOT IN ( 'ON', 'OFF' ) | |
BEGIN | |
RAISERROR('Valid value for @SORT_IN_TEMPDB is ON \ OFF',16,1) | |
RETURN | |
END | |
IF @DROP_EXISTING NOT IN ( 'ON', 'OFF' ) | |
BEGIN | |
RAISERROR('Valid value for @DROP_EXISTING is ON \ OFF',16,1) | |
RETURN | |
END | |
IF @STATISTICS_NORECOMPUTE NOT IN ( 'ON', 'OFF' ) | |
BEGIN | |
RAISERROR('Valid value for @STATISTICS_NORECOMPUTE is ON \ OFF',16,1) | |
RETURN | |
END | |
IF @ONLINE NOT IN ( 'ON', 'OFF' ) | |
BEGIN | |
RAISERROR('Valid value for @ONLINE is ON \ OFF',16,1) | |
RETURN | |
END | |
DECLARE @IDXTable TABLE | |
( | |
Schema_ID INT , | |
Object_ID INT , | |
Index_ID INT , | |
SchemaName sysname , | |
TableName sysname , | |
IndexName sysname , | |
IsPrimaryKey BIT , | |
IndexType INT , | |
CreateScript VARCHAR(MAX) NULL , | |
DropScript VARCHAR(MAX) NULL , | |
ExistsScript VARCHAR(MAX) NULL , | |
Processed BIT NULL | |
) | |
INSERT INTO @IDXTable | |
( Schema_ID , | |
Object_ID , | |
Index_ID , | |
SchemaName , | |
TableName , | |
IndexName , | |
IsPrimaryKey , | |
IndexType | |
) | |
SELECT ST.schema_id , | |
ST.object_id , | |
SI.index_id , | |
SCH.name , | |
ST.name , | |
SI.name , | |
SI.is_primary_key , | |
SI.type | |
FROM sys.indexes SI | |
JOIN sys.tables ST ON SI.object_id = ST.object_id | |
JOIN sys.schemas SCH ON SCH.schema_id = ST.schema_id | |
WHERE SCH.name = @SchemaName | |
AND ST.name = @TableName | |
AND SI.type IN ( 1, 2, 3, 4 ) | |
DECLARE @SchemaID INT | |
DECLARE @TableID INT | |
DECLARE @IndexID INT | |
DECLARE @isPrimaryKey BIT | |
DECLARE @IndexType INT | |
DECLARE @CreateSQL VARCHAR(MAX) | |
DECLARE @IndexColsSQL VARCHAR(MAX) | |
DECLARE @WithSQL VARCHAR(MAX) | |
DECLARE @IncludeSQL VARCHAR(MAX) | |
DECLARE @WhereSQL VARCHAR(MAX) | |
DECLARE @SQL VARCHAR(MAX) | |
DECLARE @DropSQL VARCHAR(MAX) | |
DECLARE @ExistsSQL VARCHAR(MAX) | |
DECLARE @IndexName sysname | |
DECLARE @TblSchemaName sysname | |
SELECT @TblSchemaName = QUOTENAME(@SchemaName) + '.' | |
+ QUOTENAME(@TableName) | |
SELECT @CreateSQL = '' | |
SELECT @IndexColsSQL = '' | |
SELECT @WithSQL = '' | |
SELECT @IncludeSQL = '' | |
SELECT @WhereSQL = '' | |
WHILE EXISTS ( SELECT 1 | |
FROM @IDXTable | |
WHERE CreateScript IS NULL ) | |
BEGIN | |
SELECT TOP 1 | |
@SchemaID = Schema_ID , | |
@TableID = Object_ID , | |
@IndexID = Index_ID , | |
@isPrimaryKey = IsPrimaryKey , | |
@IndexName = IndexName , | |
@IndexType = IndexType | |
FROM @IDXTable | |
WHERE CreateScript IS NULL | |
AND SchemaName = @SchemaName | |
AND TableName = @TableName | |
ORDER BY Index_ID | |
IF @isPrimaryKey = 1 | |
BEGIN | |
SELECT @ExistsSQL = ' EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N''' | |
+ @TblSchemaName + ''') AND name = N''' | |
+ @IndexName + ''')' | |
SELECT @DropSQL = ' ALTER TABLE ' + @TblSchemaName | |
+ ' DROP CONSTRAINT [' + @IndexName + ']' | |
END | |
ELSE | |
BEGIN | |
SELECT @ExistsSQL = ' EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N''' | |
+ @TblSchemaName + ''') AND name = N''' | |
+ @IndexName + ''')' | |
SELECT @DropSQL = ' DROP INDEX [' + @IndexName + '] ON ' | |
+ @TblSchemaName | |
+ CASE WHEN @IndexType IN ( 1, 2 ) | |
THEN ' WITH ( ONLINE = OFF )' | |
ELSE '' | |
END | |
END | |
IF @IndexType IN ( 1, 2 ) | |
BEGIN | |
SELECT @CreateSQL = CASE WHEN SI.is_primary_key = 1 | |
THEN 'ALTER TABLE ' | |
+ @TblSchemaName | |
+ ' ADD CONSTRAINT [' | |
+ @IndexName | |
+ '] PRIMARY KEY ' | |
+ SI.type_desc | |
WHEN SI.type IN ( 1, 2 ) | |
THEN ' CREATE ' | |
+ CASE SI.is_unique | |
WHEN 1 THEN ' UNIQUE ' | |
ELSE '' | |
END + SI.type_desc | |
+ ' INDEX ' | |
+ QUOTENAME(SI.name) | |
+ ' ON ' + @TblSchemaName | |
END , | |
@IndexColsSQL = ( SELECT SC.name + ' ' | |
+ CASE SIC.is_descending_key | |
WHEN 0 | |
THEN ' ASC ' | |
ELSE 'DESC' | |
END + ',' | |
FROM sys.index_columns SIC | |
JOIN sys.columns SC ON SIC.object_id = SC.object_id | |
AND SIC.column_id = SC.column_id | |
WHERE SIC.object_id = SI.object_id | |
AND SIC.index_id = SI.index_id | |
AND SIC.is_included_column = 0 | |
ORDER BY SIC.key_ordinal | |
FOR | |
XML PATH('') | |
) , | |
@WithSQL = ' WITH (PAD_INDEX = ' | |
+ CASE SI.is_padded | |
WHEN 1 THEN 'ON' | |
ELSE 'OFF' | |
END + ',' + CHAR(13) + ' IGNORE_DUP_KEY = ' | |
+ CASE SI.ignore_dup_key | |
WHEN 1 THEN 'ON' | |
ELSE 'OFF' | |
END + ',' + CHAR(13) + ' ALLOW_ROW_LOCKS = ' | |
+ CASE SI.allow_row_locks | |
WHEN 1 THEN 'ON' | |
ELSE 'OFF' | |
END + ',' + CHAR(13) + ' ALLOW_PAGE_LOCKS = ' | |
+ CASE SI.allow_page_locks | |
WHEN 1 THEN 'ON' | |
ELSE 'OFF' | |
END + ',' + CHAR(13) | |
+ CASE SI.type | |
WHEN 2 | |
THEN 'SORT_IN_TEMPDB = ' + @SORT_IN_TEMPDB | |
+ ',DROP_EXISTING = ' + @DROP_EXISTING | |
+ ',' | |
ELSE '' | |
END | |
+ CASE WHEN SI.fill_factor > 0 | |
THEN ' FILLFACTOR = ' | |
+ CONVERT(VARCHAR(3), SI.fill_factor) | |
+ ',' | |
ELSE '' | |
END + ' STATISTICS_NORECOMPUTE = ' | |
+ @STATISTICS_NORECOMPUTE + ', SORT_IN_TEMPDB = ' | |
+ @SORT_IN_TEMPDB + ', ONLINE = ' + @ONLINE | |
+ ') ON ' + QUOTENAME(SFG.name) , | |
@IncludeSQL = ( SELECT QUOTENAME(SC.name) + ',' | |
FROM sys.index_columns SIC | |
JOIN sys.columns SC ON SIC.object_id = SC.object_id | |
AND SIC.column_id = SC.column_id | |
WHERE SIC.object_id = SI.object_id | |
AND SIC.index_id = SI.index_id | |
AND SIC.is_included_column = 1 | |
ORDER BY SIC.key_ordinal | |
FOR | |
XML PATH('') | |
) , | |
@WhereSQL = SI.filter_definition | |
FROM sys.indexes SI | |
JOIN sys.filegroups SFG ON SI.data_space_id = SFG.data_space_id | |
WHERE object_id = @TableID | |
AND index_id = @IndexID | |
SELECT @IndexColsSQL = '(' + SUBSTRING(@IndexColsSQL, 1, | |
LEN(@IndexColsSQL) | |
- 1) + ')' | |
IF LTRIM(RTRIM(@IncludeSQL)) <> '' | |
SELECT @IncludeSQL = ' INCLUDE (' | |
+ SUBSTRING(@IncludeSQL, 1, | |
LEN(@IncludeSQL) - 1) + ')' | |
IF LTRIM(RTRIM(@WhereSQL)) <> '' | |
SELECT @WhereSQL = ' WHERE (' + @WhereSQL + ')' | |
END | |
IF @IndexType = 3 | |
BEGIN | |
SELECT @CreateSQL = ' CREATE ' | |
+ CASE WHEN SI.using_xml_index_id IS NULL | |
THEN ' PRIMARY ' | |
ELSE '' | |
END + SI.type_desc + ' INDEX ' | |
+ QUOTENAME(SI.name) + ' ON ' + @TblSchemaName , | |
@IndexColsSQL = ( SELECT SC.name + ' ' + ',' | |
FROM sys.index_columns SIC | |
JOIN sys.columns SC ON SIC.object_id = SC.object_id | |
AND SIC.column_id = SC.column_id | |
WHERE SIC.object_id = SI.object_id | |
AND SIC.index_id = SI.index_id | |
AND SIC.is_included_column = 0 | |
ORDER BY SIC.key_ordinal | |
FOR | |
XML PATH('') | |
) , | |
@WithSQL = ' WITH (PAD_INDEX = ' | |
+ CASE SI.is_padded | |
WHEN 1 THEN 'ON' | |
ELSE 'OFF' | |
END + ',' + CHAR(13) + ' ALLOW_ROW_LOCKS = ' | |
+ CASE SI.allow_row_locks | |
WHEN 1 THEN 'ON' | |
ELSE 'OFF' | |
END + ',' + CHAR(13) + ' ALLOW_PAGE_LOCKS = ' | |
+ CASE SI.allow_page_locks | |
WHEN 1 THEN 'ON' | |
ELSE 'OFF' | |
END + ',' + CHAR(13) | |
+ CASE SI.type | |
WHEN 2 | |
THEN 'SORT_IN_TEMPDB = OFF,DROP_EXISTING = OFF,' | |
ELSE '' | |
END | |
+ CASE WHEN SI.fill_factor > 0 | |
THEN ' FILLFACTOR = ' | |
+ CONVERT(VARCHAR(3), SI.fill_factor) | |
+ ',' | |
ELSE '' | |
END + 'SORT_IN_TEMPDB = OFF ' + ') ' , | |
@IncludeSQL = ' USING XML INDEX [' | |
+ ( SELECT name | |
FROM sys.xml_indexes SIP | |
WHERE SIP.object_id = SI.object_id | |
AND SIP.index_id = SI.using_xml_index_id | |
) + '] FOR PATH ' | |
FROM sys.xml_indexes SI | |
WHERE SI.object_id = @TableID | |
AND SI.index_id = @IndexID | |
SELECT @IndexColsSQL = '(' + SUBSTRING(@IndexColsSQL, 1, | |
LEN(@IndexColsSQL) | |
- 1) + ')' | |
END | |
IF @IndexType = 4 | |
BEGIN | |
SELECT @CreateSQL = ' CREATE SPATIAL INDEX ' | |
+ QUOTENAME(SI.name) + ' ON ' + @TblSchemaName , | |
@IndexColsSQL = ( SELECT '(' | |
+ QUOTENAME(SC.name) | |
+ ') ' | |
FROM sys.index_columns SIC | |
JOIN sys.columns SC ON SIC.object_id = SC.object_id | |
AND SIC.column_id = SC.column_id | |
WHERE SIC.object_id = SI.object_id | |
AND SIC.index_id = SI.index_id | |
AND SIC.is_included_column = 0 | |
) , | |
@WithSQL = ' WITH (' | |
+ +' BOUNDING_BOX = ( XMIN = ' | |
+ CONVERT(VARCHAR(25), SIT.bounding_box_xmin) | |
+ ', YMIN = ' | |
+ CONVERT(VARCHAR(25), SIT.bounding_box_ymin) + ',' | |
+ ' XMAX = ' | |
+ CONVERT(VARCHAR(25), SIT.bounding_box_xmax) | |
+ ', YMAX = ' | |
+ CONVERT(VARCHAR(25), SIT.bounding_box_ymax) | |
+ ' ), ' + CHAR(13) + ' CELLS_PER_OBJECT = ' | |
+ CONVERT(VARCHAR(3), SIT.cells_per_object) | |
+ CHAR(13) | |
+ CASE WHEN SIT.level_1_grid IS NOT NULL | |
THEN ' , GRIDS = ( LEVEL_1 = ' | |
+ SIT.level_1_grid_desc | |
+ ', LEVEL_2 = ' | |
+ SIT.level_2_grid_desc | |
+ ', LEVEL_3 = ' | |
+ SIT.level_3_grid_desc | |
+ ', LEVEL_4 = ' | |
+ SIT.level_4_grid_desc + ' ) ' | |
ELSE '' | |
END + ', PAD_INDEX = ' + CASE SI.is_padded | |
WHEN 1 THEN 'ON' | |
ELSE 'OFF' | |
END + ',' + CHAR(13) | |
+ ' ALLOW_ROW_LOCKS = ' + CASE SI.allow_row_locks | |
WHEN 1 THEN 'ON' | |
ELSE 'OFF' | |
END + ',' + CHAR(13) | |
+ ' ALLOW_PAGE_LOCKS = ' | |
+ CASE SI.allow_page_locks | |
WHEN 1 THEN 'ON' | |
ELSE 'OFF' | |
END + ',' + CHAR(13) | |
+ CASE SI.type | |
WHEN 2 | |
THEN 'SORT_IN_TEMPDB = OFF,DROP_EXISTING = OFF,' | |
ELSE '' | |
END | |
+ CASE WHEN SI.fill_factor > 0 | |
THEN ' FILLFACTOR = ' | |
+ CONVERT(VARCHAR(3), SI.fill_factor) | |
+ ',' | |
ELSE '' | |
END + 'SORT_IN_TEMPDB = OFF ' + CHAR(13) + ') ' , | |
@IncludeSQL = ' USING ' + SI.tessellation_scheme | |
FROM sys.spatial_indexes SI | |
JOIN sys.spatial_index_tessellations SIT ON SIT.index_id = SI.index_id | |
AND SIT.object_id = SI.object_id | |
WHERE SI.[object_id] = @TableID | |
AND SI.index_id = @IndexID | |
END | |
SELECT @CreateSQL = @CreateSQL + @IndexColsSQL | |
+ CASE WHEN @IndexColsSQL <> '' THEN CHAR(13) | |
ELSE '' | |
END + ISNULL(@IncludeSQL, '') | |
+ CASE WHEN @IncludeSQL <> '' THEN CHAR(13) | |
ELSE '' | |
END + ISNULL(@WhereSQL, '') | |
+ CASE WHEN @WhereSQL <> '' THEN CHAR(13) | |
ELSE '' | |
END + @WithSQL | |
UPDATE @IDXTable | |
SET CreateScript = @CreateSQL , | |
DropScript = @DropSQL , | |
ExistsScript = @ExistsSQL | |
WHERE Schema_ID = @SchemaID | |
AND Object_ID = @TableID | |
AND Index_ID = @IndexID | |
END | |
PRINT REPLICATE('-', 100) | |
PRINT '-- DROP Indexes' | |
PRINT REPLICATE('-', 100) | |
UPDATE @IDXTable | |
SET Processed = 0 | |
WHERE SchemaName = @SchemaName | |
AND TableName = @TableName | |
WHILE EXISTS ( SELECT 1 | |
FROM @IDXTable | |
WHERE ISNULL(Processed, 0) = 0 | |
AND SchemaName = @SchemaName | |
AND TableName = @TableName ) | |
BEGIN | |
SELECT @SQL = '' | |
SELECT TOP 1 | |
@SchemaID = Schema_ID , | |
@TableID = Object_ID , | |
@IndexID = Index_ID , | |
@SQL = 'IF ' + ExistsScript + CHAR(13) + DropScript | |
+ CHAR(13) | |
FROM @IDXTable | |
WHERE ISNULL(Processed, 0) = 0 | |
AND SchemaName = @SchemaName | |
AND TableName = @TableName | |
ORDER BY IndexType DESC , | |
Index_ID DESC | |
PRINT @SQL | |
UPDATE @IDXTable | |
SET Processed = 1 | |
WHERE Schema_ID = @SchemaID | |
AND Object_ID = @TableID | |
AND Index_ID = @IndexID | |
END | |
PRINT REPLICATE('-', 100) | |
PRINT '-- Create Indexes' | |
PRINT REPLICATE('-', 100) | |
UPDATE @IDXTable | |
SET Processed = 0 | |
WHERE SchemaName = @SchemaName | |
AND TableName = @TableName | |
WHILE EXISTS ( SELECT 1 | |
FROM @IDXTable | |
WHERE ISNULL(Processed, 0) = 0 | |
AND SchemaName = @SchemaName | |
AND TableName = @TableName ) | |
BEGIN | |
SELECT @SQL = '' | |
SELECT TOP 1 | |
@SchemaID = Schema_ID , | |
@TableID = Object_ID , | |
@IndexID = Index_ID , | |
@SQL = 'IF NOT ' + ExistsScript + CHAR(13) + CreateScript | |
+ CHAR(13) | |
FROM @IDXTable | |
WHERE ISNULL(Processed, 0) = 0 | |
AND SchemaName = @SchemaName | |
AND TableName = @TableName | |
-- make sure spatial are always last | |
ORDER BY ( ISNULL(NULLIF(IndexType, 4), -1) ) DESC , | |
Index_ID DESC | |
PRINT @SQL | |
UPDATE @IDXTable | |
SET Processed = 1 | |
WHERE Schema_ID = @SchemaID | |
AND Object_ID = @TableID | |
AND Index_ID = @IndexID | |
END | |
GO | |
--EXEC ScriptCreateDropIndexes_SP @TableName ='Personme',@SchemaName ='Person' | |