/*
Server:		samnb705db01.amavita.ch
Format:		GCM 
Business:	TPPHAR
type:		VALI
Version:	23.1.21006.00066

06.06.2024, TSC
*/
;WITH ColInfo
   AS (SELECT      TblName = o.name,
                   SchemaTbl = s.name + '.' + o.name,
                   IndexName = i.name,
                   IsPrimaryKey = [i].[is_primary_key],
                   IsUniqueConstraint = [i].[is_unique_constraint],
                   IsUnique = [i].[is_unique],
                   ColName = c.name,
                   IsComputedCol = [c].[is_computed],
                   IsIncludedCol = [ic].[is_included_column],
                   [ic].[key_ordinal],
                   FilterDefinition = [i].[filter_definition],
                   i.[index_id],
                   crlf = CHAR(13) + CHAR(10),
                   crlfgo = ';' + CHAR(13) + CHAR(10) + 'GO' + CHAR(13) + CHAR(10),
                   [o].[object_id]
         FROM      sys.objects o
        INNER JOIN sys.schemas s
           ON o.schema_id = s.schema_id
        INNER JOIN sys.columns c
           ON o.object_id = c.object_id
        INNER JOIN sys.indexes i
           ON c.object_id = i.object_id
        INNER JOIN sys.index_columns ic
           ON i.index_id  = ic.index_id
          AND o.object_id = ic.object_id
          AND c.column_id = ic.column_id
        WHERE      s.name = 'dbo'
          AND      o.name = 'account_chart'
--AND i.filter_definition IS NOT NULL
)
SELECT       DISTINCT [x].[TblName],
                      [x].[IndexName],
                      [x].[index_id],
                      [x].[IsPrimaryKey],
                      [x].[IsUniqueConstraint],
                      [x].[IsUnique],
                      --,size.IndexSizeKB
                      [c].[IndexColumns],
                      [ci].[IncludedColumns],
                      [cc].[ComputedColumns],
                      [x].[FilterDefinition],
                      [sz].[IndexSizeMB],
                      [us].[Reads],
                      [us].[Writes],
                      DropCreateSQL = [x].[crlf] + '-- ' + x.IndexName + [x].[crlf] +
                      --check drop
                      'IF INDEXPROPERTY(OBJECT_ID(''' + [x].[SchemaTbl] + '''), ''' + x.IndexName
                                      + ''' , ''IndexID'' ) IS NOT NULL BEGIN;' + [x].[crlf]
                                      + CASE
                                             WHEN [x].[IsPrimaryKey] = 1 THEN NULL
                                             WHEN [x].[IsUniqueConstraint] = 1 THEN
                                               --drop statement
                                               '    ALTER TABLE ' + [x].[SchemaTbl] + ' DROP CONSTRAINT ' + x.IndexName + ';'
                                               + [x].[crlf] + 'END' + [x].[crlfgo]
                                               --check create
                                               + 'IF INDEXPROPERTY(OBJECT_ID(''' + [x].[SchemaTbl] + '''), ''' + x.IndexName
                                               + ''' , ''IndexID'' ) IS NULL BEGIN;' + [x].[crlf] +
                      --create statement
                      +'    ALTER TABLE '
                                               + [x].[SchemaTbl] + ' ADD CONSTRAINT ' + x.IndexName + ' UNIQUE ('
                                               + [c].[IndexColumns] + ');' + [x].[crlf] + 'END' + [x].[crlfgo]
                                             ELSE
                                               --drop statement
                                               '    DROP INDEX ' + [x].[SchemaTbl] + '.' + x.IndexName + ';' + [x].[crlf]
                                               + 'END' + [x].[crlfgo]
                                               --check create
                                               + 'IF INDEXPROPERTY(OBJECT_ID(''' + [x].[SchemaTbl] + '''), ''' + x.IndexName
                                               + ''' , ''IndexID'' ) IS NULL BEGIN;' + [x].[crlf] +
                      --create statement
                      +'    CREATE '
                                               + CASE
                                                      WHEN [x].[IsUnique] = 1 THEN 'UNIQUE '
                                                      ELSE '' END + 'INDEX ' + x.IndexName + ' ON ' + [x].[SchemaTbl] + '('
                                               + [c].[IndexColumns] + ')'
                                               + ISNULL(' INCLUDE(' + [ci].[IncludedColumns] + ')', '')
                                               + ISNULL(' WHERE ' + [x].[FilterDefinition], '') + ';' + [x].[crlf] + 'END'
                                               + [x].[crlfgo] END
  FROM       ColInfo x
 OUTER APPLY ( SELECT IndexColumns = STUFF([sq].[strXML], 1, 2, '')
                 FROM ( SELECT ', ' + ISNULL([x2].[ColName], '')
                          FROM ColInfo x2
                         WHERE x.TblName            = [x2].[TblName]
                           AND x.IndexName          = [x2].[IndexName]
                           AND [x2].[IsIncludedCol] = 0
                         ORDER BY x2.key_ordinal
                        FOR XML PATH('')) sq(strXML) ) c
 OUTER APPLY ( SELECT IncludedColumns = STUFF([sq].[strXML], 1, 2, '')
                 FROM ( SELECT ', ' + ISNULL([x2].[ColName], '')
                          FROM ColInfo x2
                         WHERE x.TblName            = [x2].[TblName]
                           AND x.IndexName          = [x2].[IndexName]
                           AND [x2].[IsIncludedCol] = 1
                         ORDER BY x2.key_ordinal
                        FOR XML PATH('')) sq(strXML) ) ci
 OUTER APPLY ( SELECT ComputedColumns = STUFF([sq].[strXML], 1, 2, '')
                 FROM ( SELECT ', ' + ISNULL([x2].[ColName], '')
                          FROM ColInfo x2
                         WHERE x.TblName            = [x2].[TblName]
                           AND x.IndexName          = [x2].[IndexName]
                           AND [x2].[IsComputedCol] = 1
                         ORDER BY x2.key_ordinal
                        FOR XML PATH('')) sq(strXML) ) cc
 OUTER APPLY ( SELECT      tblName = o.name,
                           o.type,
                           i.name AS [IndexName],
                           i.index_id,
                           [s].[user_seeks] + [s].[user_scans] + [s].[user_lookups] AS [Reads],
                           [s].[user_updates] AS [Writes],
                           i.type_desc AS [IndexType],
                           [i].[fill_factor] AS [FillFactor],
                           [i].[has_filter],
                           [i].[filter_definition],
                           [s].[last_user_scan],
                           [s].[last_user_lookup],
                           [s].[last_user_seek]
                 FROM      sys.dm_db_index_usage_stats AS s WITH (NOLOCK)
                INNER JOIN sys.indexes AS i WITH (NOLOCK)
                   ON s.object_id = i.object_id
                INNER JOIN sys.objects o WITH (NOLOCK)
                   ON s.object_id = o.object_id
                WHERE      o.type       = 'U' -- user table
                  AND      i.index_id        = s.index_id
                  AND      [s].[database_id] = DB_ID()
                  AND      o.name            = x.TblName
                  AND      i.name            = x.IndexName) us
 OUTER APPLY ( SELECT [i].[name] AS IndexName,
                      SUM([s].[used_page_count]) * 8 / 1024 AS IndexSizeMB
                 FROM sys.dm_db_partition_stats AS s
                 JOIN sys.indexes AS i
                   ON s.[object_id] = i.[object_id]
                  AND s.index_id    = i.index_id
                WHERE s.[object_id] = x.[object_id] --OBJECT_ID('dbo.document_line')
                  AND [i].[name]    = x.IndexName
                GROUP BY [i].[name]) sz
ORDER BY [x].[index_id];
