• wow this script has come a long way since the original version; thanks again to everyone who has contributed;

    I cleaned up the formatting a little bit and added some comments, so that folks run this against SQL 2005 don't panic when it fails due to the new filtered indexes;

    --Script SQL 2008+ Indexes AS CREATE INDEX Statements

    --http://www.sqlservercentral.com/Forums/Topic401795-566-1.aspx

    --original version submitted by anonymous/unknown contributor

    --enhanced and contributed to discussion by Lowell

    --enhanced by thorv-918308 to correct index columns in the correct sequence

    --enhanced by thorv-918308 added fill factor, and with ONLINE = ON

    --enhanced by mfuller333 to include DROP statements!

    --enhanced by Sander A. to include filtered indexes!

    --enhanced by craigborri to put the clustered indexes first, you'll want to do if you ever run this for real

    /*if you get this error:

    Msg 207, Level 16, State 1, Line 22

    Invalid column name 'filter_definition'.

    Msg 207, Level 16, State 1, Line 24

    Invalid column name 'filter_definition'.

    Msg 208, Level 16, State 0, Line 11

    Invalid object name '#tmp_indexes'.

    the issue is the database in question is SQL 2005: filter_definition is SQL 2008

    see the inline code to comment/uncomment to make this SQL 2005 compliant.

    */

    --################################################################################################

    --1. get all indexes from current db, place in temp table

    --################################################################################################

    SELECT

    tablename = QUOTENAME(scmz.name) + '.' + QUOTENAME((OBJECT_NAME(ixz.object_id))),

    tableid = ixz.object_id,

    indexid = ixz.index_id,

    indexname = ixz.name,

    isunique = INDEXPROPERTY (ixz.object_id,ixz.name,'isunique'),

    isclustered = INDEXPROPERTY (ixz.object_id,ixz.name,'isclustered'),

    indexfillfactor = INDEXPROPERTY (ixz.object_id,ixz.name,'indexfillfactor'),

    --SQL2008+ Filtered indexes:

    CASE

    WHEN ixz.filter_definition IS NULL

    THEN ''

    ELSE ' WHERE ' + ixz.filter_definition

    END Filter_Definition

    --For 2005, which did not have filtered indexes, comment out the above CASE statement, and uncomment this:

    --'' AS Filter_Definition

    INTO #tmp_indexes

    FROM sys.indexes ixz

    INNER JOIN sys.objects obz

    ON ixz.object_id = obz.object_id

    INNER JOIN sys.schemas scmz

    ON obz.schema_id = scmz.schema_id

    WHERE ixz.index_id > 0

    AND ixz.index_id < 255 ---- 0 = HEAP index, 255 = TEXT columns index

    AND INDEXPROPERTY (ixz.object_id,ixz.name,'ISUNIQUE') = 0 -- comment out to include unique and

    AND INDEXPROPERTY (ixz.object_id,ixz.name,'ISCLUSTERED') = 0 -- comment out to include PK's

    --add additional columns to store include and key column lists

    ALTER TABLE #tmp_indexes ADD keycolumns VARCHAR(4000), includes VARCHAR(4000)

    GO

    --################################################################################################

    --2. loop through tables, put include and index columns into variables

    --################################################################################################

    DECLARE @isql_key VARCHAR(4000),

    @isql_incl VARCHAR(4000),

    @tableid INT,

    @indexid INT

    DECLARE index_cursor CURSOR

    FOR

    SELECT

    tableid,

    indexid

    FROM #tmp_indexes

    --################################################################################################

    --Cursor Block

    --################################################################################################

    OPEN index_cursor

    FETCH NEXT FROM index_cursor INTO @tableid, @indexid

    WHILE @@FETCH_STATUS <> -1

    BEGIN

    SELECT @isql_key = '', @isql_incl = ''

    SELECT --ixz.name, colz.colid, colz.name, ixcolz.index_id, ixcolz.object_id, *

    --key column

    @isql_key = CASE ixcolz.is_included_column

    WHEN 0

    THEN CASE ixcolz.is_descending_key

    WHEN 1

    THEN @isql_key + COALESCE(colz.name,'') + ' DESC, '

    ELSE @isql_key + COALESCE(colz.name,'') + ' ASC, '

    END

    ELSE @isql_key

    END,

    --include column

    @isql_incl = CASE ixcolz.is_included_column

    WHEN 1

    THEN CASE ixcolz.is_descending_key

    WHEN 1

    THEN @isql_incl + COALESCE(colz.name,'') + ', '

    ELSE @isql_incl + COALESCE(colz.name,'') + ', '

    END

    ELSE @isql_incl

    END

    FROM sysindexes ixz

    INNER JOIN sys.index_columns AS ixcolz

    ON (ixcolz.column_id > 0

    AND ( ixcolz.key_ordinal > 0

    OR ixcolz.partition_ordinal = 0

    OR ixcolz.is_included_column != 0)

    )

    AND ( ixcolz.index_id=CAST(ixz.indid AS INT)

    AND ixcolz.object_id=ixz.id

    )

    INNER JOIN sys.columns AS colz

    ON colz.object_id = ixcolz.object_id

    AND colz.column_id = ixcolz.column_id

    WHERE ixz.indid > 0 AND ixz.indid < 255

    AND (ixz.status & 64) = 0

    AND ixz.id = @tableid

    AND ixz.indid = @indexid

    ORDER BY

    ixz.name,

    CASE ixcolz.is_included_column

    WHEN 1

    THEN ixcolz.index_column_id

    ELSE ixcolz.key_ordinal

    END

    --remove any trailing commas from the cursor results

    IF LEN(@isql_key) > 1 SET @isql_key = LEFT(@isql_key, LEN(@isql_key) -1)

    IF LEN(@isql_incl) > 1 SET @isql_incl = LEFT(@isql_incl, LEN(@isql_incl) -1)

    --put the columns collection into our temp table

    UPDATE #tmp_indexes

    SET keycolumns = @isql_key,

    includes = @isql_incl

    WHERE tableid = @tableid

    AND indexid = @indexid

    FETCH NEXT FROM index_cursor INTO @tableid,@indexid

    END --WHILE

    --################################################################################################

    --End Cursor Block

    --################################################################################################

    CLOSE index_cursor

    DEALLOCATE index_cursor

    --remove invalid indexes, ie ones without key columns

    DELETE FROM #tmp_indexes WHERE keycolumns = ''

    --################################################################################################

    --3. output the index creation scripts

    --################################################################################################

    SET NOCOUNT ON

    --separator for results-to-text

    SELECT '---------------------------------------------------------------------'

    --create index scripts (for backup)

    SELECT 'IF NOT EXISTS(SELECT OBJECT_ID(' + INDEXNAME + ')' + ' ' +

    'CREATE '

    + CASE WHEN ISUNIQUE = 1 THEN 'UNIQUE ' ELSE '' END

    + CASE WHEN ISCLUSTERED = 1 THEN 'CLUSTERED ' ELSE '' END

    + 'INDEX ' + QUOTENAME(INDEXNAME)

    + ' ON ' + (TABLENAME) + ' '

    + '(' + keycolumns + ')'

    + CASE

    WHEN INDEXFILLFACTOR = 0 AND ISCLUSTERED = 1 AND INCLUDES = '' THEN Filter_Definition

    WHEN INDEXFILLFACTOR = 0 AND ISCLUSTERED = 0 AND INCLUDES = '' THEN Filter_Definition + ' WITH (ONLINE = ON)'

    WHEN INDEXFILLFACTOR <> 0 AND ISCLUSTERED = 0 AND INCLUDES = '' THEN Filter_Definition + ' WITH (ONLINE = ON, FILLFACTOR = ' + CONVERT(VARCHAR(10),INDEXFILLFACTOR) + ')'

    WHEN INDEXFILLFACTOR = 0 AND ISCLUSTERED = 0 AND INCLUDES <> '' THEN ' INCLUDE (' + INCLUDES + ') ' + Filter_Definition + ' WITH (ONLINE = ON)'

    ELSE ' INCLUDE(' + INCLUDES + ') ' + Filter_Definition + ' WITH (FILLFACTOR = ' + CONVERT(VARCHAR(10),INDEXFILLFACTOR) + ', ONLINE = ON)'

    END

    FROM #tmp_indexes

    WHERE LEFT(tablename,3) NOT IN ('sys', 'dt_') --exclude system tables

    ORDER BY

    ISCLUSTERED desc,

    tablename,

    indexid,

    indexname

    --makes the drop

    SELECT

    'DROP INDEX '

    + ' ' + (tablename) + '.'

    + (indexname) + ''

    FROM #tmp_indexes

    WHERE LEFT(tablename,4) NOT IN ('[sys', 'dt_')

    --Drop the temp table again

    DROP TABLE #tmp_indexes

    SET NOCOUNT OFF

    Lowell


    --help us help you! If you post a question, make sure you include a CREATE TABLE... statement and INSERT INTO... statement into that table to give the volunteers here representative data. with your description of the problem, we can provide a tested, verifiable solution to your question! asking the question the right way gets you a tested answer the fastest way possible!