如何在知道其名称时获取索引创建脚本

时间:2016-11-14 15:29:18

标签: sql-server

我有一个创建游标的请求,该游标解析包含索引名称列表的临时表,并为临时表中找到的每个名称生成创建索引脚本,并将这些创建索引语句存储到另一个临时表中。花了半天时间尝试这个没有用。任何建议都非常感谢。

1 个答案:

答案 0 :(得分:1)

我刚才从各种来源编译过它,它应该为你提供数据库中所有索引的创建和删除脚本;

/* Check if our first temp table already exists and drop if so */

IF OBJECT_ID('tempdb..#CreateIndexes') IS NOT NULL DROP TABLE #CreateIndexes
GO

/* Let's declare some variables shall we */

declare @SchemaName varchar(100)declare @TableName varchar(256)
declare @IndexName varchar(256)
declare @ColumnName varchar(100)
declare @is_unique varchar(100)
declare @IndexTypeDesc varchar(100)
declare @FileGroupName varchar(100)
declare @is_disabled varchar(100)
declare @IndexOptions varchar(max)
declare @IndexColumnId int
declare @IsDescendingKey int 
declare @IsIncludedColumn int
declare @TSQLScripCreationIndex varchar(max)
declare @TSQLScripDisableIndex varchar(max)

/* Make a table to insert our results into */

CREATE TABLE #CreateIndexes (
                            SchemaName varchar(max)
                            ,TableName varchar(max)
                            ,IndexName varchar(max)
                            ,is_unique varchar(max)
                            ,IndexTypeDesc varchar(max)
                            ,is_disabled varchar(max)
                            ,FileGroupName varchar(max)
                            ,DropScript varchar(max)
                            ,TSQLScripCreationIndex varchar(max)
                            ,TSQLScripDisableIndex varchar(max)
                            ,TSQLDropIndex varchar(max)
                            )

/* Cursor *shudder* to gather index info, make our create scripts and push into our temp table */

DECLARE CursorIndex CURSOR FOR
 SELECT 
    schema_name(t.schema_id) [schema_name]
    ,t.name
    ,ix.name
    ,CASE   
        WHEN ix.is_unique = 1 
            THEN 'UNIQUE ' 
        ELSE '' 
     END 
    ,ix.type_desc
    ,   CASE
           WHEN ix.is_padded=1 
               THEN 'PAD_INDEX = ON, ' 
           ELSE 'PAD_INDEX = OFF, ' 
        END
        + 
        CASE
           WHEN ix.allow_page_locks=1 
               THEN 'ALLOW_PAGE_LOCKS = ON, ' 
           ELSE 'ALLOW_PAGE_LOCKS = OFF, ' 
        END
        + 
        CASE
           WHEN ix.allow_row_locks=1 
               THEN  'ALLOW_ROW_LOCKS = ON, ' 
           ELSE 'ALLOW_ROW_LOCKS = OFF, ' 
        END
        + 
        CASE
           WHEN INDEXPROPERTY(t.object_id, ix.name, 'IsStatistics') = 1 
               THEN 'STATISTICS_NORECOMPUTE = ON, ' 
           ELSE 'STATISTICS_NORECOMPUTE = OFF, ' 
        END
        + 
        CASE
           WHEN ix.ignore_dup_key=1 
               THEN 'IGNORE_DUP_KEY = ON, ' 
           ELSE 'IGNORE_DUP_KEY = OFF, ' 
        END
        + 
        'SORT_IN_TEMPDB = OFF, FILLFACTOR =' 
        + 
        CAST(ix.fill_factor AS VARCHAR(3)) 
    AS IndexOptions
    ,ix.is_disabled 
    ,FILEGROUP_NAME(ix.data_space_id) FileGroupName
 FROM sys.tables t 
 INNER JOIN sys.indexes ix 
    ON t.object_id=ix.object_id
 WHERE ix.type>0 
    AND ix.is_primary_key=0 
    AND ix.is_unique_constraint=0 
    --and schema_name(tb.schema_id)= @SchemaName and tb.name=@TableName
    AND t.is_ms_shipped=0 
    AND t.name<>'sysdiagrams'
 ORDER BY schema_name(t.schema_id)
    ,t.name
    ,ix.name

OPEN CursorIndex
FETCH NEXT FROM CursorIndex INTO  @SchemaName, @TableName, @IndexName, @is_unique, @IndexTypeDesc, @IndexOptions,@is_disabled, @FileGroupName

WHILE (@@fetch_status=0)
BEGIN
 DECLARE @IndexColumns varchar(max)
 DECLARE @IncludedColumns varchar(max)

 SET @IndexColumns=''
 SET @IncludedColumns=''

 DECLARE CursorIndexColumn CURSOR FOR 
  SELECT col.name, ixc.is_descending_key, ixc.is_included_column
  FROM sys.tables tb 
  INNER JOIN sys.indexes ix on tb.object_id=ix.object_id
  INNER JOIN sys.index_columns ixc on ix.object_id=ixc.object_id and ix.index_id= ixc.index_id
  INNER JOIN sys.columns col on ixc.object_id =col.object_id  and ixc.column_id=col.column_id
  WHERE ix.type>0 and (ix.is_primary_key=0 or ix.is_unique_constraint=0)
  AND schema_name(tb.schema_id)=@SchemaName and tb.name=@TableName and ix.name=@IndexName
  ORDER BY ixc.index_column_id

 OPEN CursorIndexColumn 
 FETCH NEXT FROM CursorIndexColumn INTO  @ColumnName, @IsDescendingKey, @IsIncludedColumn

 WHILE (@@fetch_status=0)
 BEGIN
  IF @IsIncludedColumn=0 
   SET @IndexColumns=@IndexColumns + @ColumnName  + CASE WHEN @IsDescendingKey=1  THEN ' DESC, ' ELSE  ' ASC, ' END
  ELSE 
   SET @IncludedColumns=@IncludedColumns  + @ColumnName  +', ' 

  FETCH NEXT FROM CursorIndexColumn INTO @ColumnName, @IsDescendingKey, @IsIncludedColumn
 END

 CLOSE CursorIndexColumn
 DEALLOCATE CursorIndexColumn

 SET @IndexColumns = substring(@IndexColumns, 1, len(@IndexColumns)-1)
 SET @IncludedColumns = CASE WHEN len(@IncludedColumns) >0 THEN substring(@IncludedColumns, 1, len(@IncludedColumns)-1) ELSE '' END
 --  print @IndexColumns
 --  print @IncludedColumns

 SET @TSQLScripCreationIndex =''
 SET @TSQLScripDisableIndex =''
 SET @TSQLScripCreationIndex='CREATE '+ @is_unique  +@IndexTypeDesc + ' INDEX ' +QUOTENAME(@IndexName)+' ON ' + QUOTENAME(@SchemaName) +'.'+ QUOTENAME(@TableName)+ '('+@IndexColumns+') '+ 
  CASE WHEN len(@IncludedColumns)>0 THEN CHAR(13) +'INCLUDE (' + @IncludedColumns+ ')' ELSE '' END + CHAR(13)+'WITH (' + @IndexOptions+ ') ON ' + QUOTENAME(@FileGroupName) + ';'  

 IF @is_disabled=1 
  SET  @TSQLScripDisableIndex=  CHAR(13) +'ALTER INDEX ' +QUOTENAME(@IndexName) + ' ON ' + QUOTENAME(@SchemaName) +'.'+ QUOTENAME(@TableName) + ' DISABLE;' + CHAR(13) 

 PRINT @TSQLScripCreationIndex
 PRINT @TSQLScripDisableIndex

 INSERT INTO #CreateIndexes (SchemaName, TableName, IndexName, is_unique, IndexTypeDesc, is_disabled, FileGroupName, TSQLScripCreationIndex, TSQLScripDisableIndex)
 SELECT @SchemaName, @TableName, @IndexName, @is_unique, @IndexTypeDesc, @is_disabled, @FileGroupName, @TSQLScripCreationIndex, @TSQLScripDisableIndex

 FETCH NEXT FROM CursorIndex INTO  @SchemaName, @TableName, @IndexName, @is_unique, @IndexTypeDesc, @IndexOptions,@is_disabled, @FileGroupName

END
CLOSE CursorIndex
DEALLOCATE CursorIndex


/*Right, let's look at creating our drop index scripts then*/

IF OBJECT_ID('tempdb..#DropIndex') IS NOT NULL DROP TABLE #DropIndex
GO

DECLARE @SchemaName VARCHAR(256)
DECLARE @TableName VARCHAR(256)
DECLARE @IndexName VARCHAR(256)
DECLARE @TSQLDropIndex VARCHAR(MAX)

CREATE TABLE #DropIndex (SchemaName varchar(max), TableName varchar(max),IndexName varchar(max), DropScript varchar(max))

DECLARE CursorIndexes CURSOR FOR
    SELECT 
       schema_name(t.schema_id)
       ,t.name
       ,i.name 
    FROM sys.indexes i
    INNER JOIN sys.tables t 
        ON t.object_id= i.object_id
    WHERE i.type>0 
        AND t.is_ms_shipped=0 
        AND t.name<>'sysdiagrams'
        AND (is_primary_key=0 and is_unique_constraint=0)

OPEN CursorIndexes
FETCH NEXT FROM CursorIndexes INTO @SchemaName,@TableName,@IndexName

WHILE @@fetch_status = 0
BEGIN
 SET @TSQLDropIndex = 'INSERT INTO #DropIndex (SchemaName, TableName, IndexName, DropScript) VALUES (' + CHAR(39) + @SchemaName + CHAR(39) + ', ' + CHAR(39) + @TableName + CHAR(39) + ', ' + CHAR(39) + @IndexName + CHAR(39) + ', ' + CHAR(39) + 'DROP INDEX ' + QUOTENAME(@SchemaName) + '.' + QUOTENAME(@TableName) + '.' +QUOTENAME(@IndexName) + CHAR(39) + ')'
 EXEC (@TSQLDropIndex)
 FETCH NEXT FROM CursorIndexes INTO @SchemaName,@TableName,@IndexName
END

CLOSE CursorIndexes
DEALLOCATE CursorIndexes 


UPDATE ci
SET TSQLDropIndex = di.DropScript
FROM #CreateIndexes ci
JOIN #DropIndex di 
ON ci.SchemaName = di.SchemaName 
AND ci.TableName = di.TableName 
AND ci.IndexName = di.IndexName

SELECT 
* FROM #CreateIndexes

它应该让你知道你将要适用于自己的情况。