【问题标题】:Generate script of all indexes, keys in the SQL Server database生成 SQL Server 数据库中所有索引、键的脚本
【发布时间】:2013-09-07 18:01:17
【问题描述】:

我希望生成如下脚本:

ALTER TABLE dbo.Person 
    ADD CONSTRAINT PK_Person PRIMARY KEY CLUSTERED (PersonID);
    CREATE INDEX IX_EVT_EVENTS on EVT_EVENTS(prg_event_t1, prg_event_t2, num_order)

我找不到我需要的所有信息的主要问题,例如这个查询:

SELECT t.name TableName, I.* 
FROM sys.indexes I 
Inner Join sys.tables T on i.object_id=t.object_id

返回有关所有键和索引的信息,但是.. 没有“列名”我在哪里可以得到它们?

我也尝试了 sys.all_columns 和 sys.key_constraints。

【问题讨论】:

标签: sql sql-server tsql indexing


【解决方案1】:

我在 web.xml 中尝试了许多脚本。他们都有缺陷。我终于使用 msdn 网站上的帖子编写了我的脚本,并将其更改为适用于多种情况。

注意:此脚本适用于 SQL Server 2012 及更高版本

WITH IndexInfo AS (
SELECT ix.object_id
    , ix.NAME AS IndexName
    , ix.type_desc
    , ix.filter_definition
    , ix.is_unique
    , ix.is_primary_key
    , ix.allow_row_locks
    , ix.allow_page_locks
    , ds.NAME AS DataSpaceName
    , ds.type AS DataSpaceType
    , ix.is_padded
    , object_schema_name(ix.object_id) AS SchemaName
    , object_name(ix.object_id) AS TableName
    , IIF(ix.type <= 2, is_included_column, 0) AS HasIncludedColumn
    , IIF(ix.type in (5, 6), 1, 0) AS IsColumnStore
    , (
        SELECT KeyColumns
        FROM (
            SELECT IC2.object_id
                , IC2.index_id
                , STUFF((
                        SELECT ' , ' + C.NAME + IIF(MAX(CONVERT(INT, IC1.is_descending_key)) = 1 AND ix.type <= 2, ' DESC ', ' ')
                        FROM sys.index_columns IC1
                        JOIN sys.columns C ON C.object_id = IC1.object_id
                            AND C.column_id = IC1.column_id
                            --AND IC1.is_included_column = 0   
                            AND IIF(ix.type <= 2, IC1.is_included_column, 0) = 0
                            AND IIF(ix.type <= 2, IC1.key_ordinal, ic.index_column_id) > 0
                        WHERE IC1.object_id = IC2.object_id
                            AND IC1.index_id = IC2.index_id
                        GROUP BY IC1.object_id
                            , C.NAME
                            , index_id
                            , IC1.key_ordinal
                            , IC1.index_column_id
                        ORDER BY IIF(ix.type <= 2, IC1.key_ordinal, IC1.index_column_id)
                        FOR XML PATH('')
                        ), 1, 2, '') KeyColumns
            FROM sys.index_columns IC2
            GROUP BY IC2.object_id
                , IC2.index_id
            ) tmp
        WHERE tmp.object_id = ix.object_id
            AND tmp.index_id = ix.index_id
        ) AS KeyColumnsStr
    , (
        SELECT IncludedColumns
        FROM (
            SELECT IC2.object_id, IC2.index_id
                , STUFF((
                        SELECT ' , ' + C.NAME
                        FROM sys.index_columns IC1
                        JOIN sys.columns C ON C.object_id = IC1.object_id
                            AND C.column_id = IC1.column_id
                            --AND IC1.is_included_column = 1   
                            AND IIF(ix.type <= 2, IC1.is_included_column, 0) <> 0
                        WHERE IC1.object_id = IC2.object_id
                            AND IC1.index_id = IC2.index_id
                        --and IIF(ix.type <= 2, IC1.key_ordinal, ic.index_column_id) > 0
                        GROUP BY IC1.object_id, C.NAME, index_id, IC1.key_ordinal, IC1.index_column_id
                        ORDER BY IIF(ix.type <= 2, IC1.key_ordinal, IC1.index_column_id)
                        FOR XML PATH('')
                        ), 1, 2, '') IncludedColumns
            FROM sys.index_columns IC2
            GROUP BY IC2.object_id, IC2.index_id
            ) tmp
        WHERE tmp.object_id = ix.object_id
            AND tmp.index_id = ix.index_id
            AND IncludedColumns IS NOT NULL
        ) AS IncludedColumnsStr
FROM sys.indexes ix
INNER JOIN sys.index_columns ic ON ic.index_id = ix.index_id AND ic.object_id = ix.object_id
INNER JOIN sys.columns col ON col.column_id = ic.column_id AND col.object_id = ix.object_id
INNER JOIN sys.data_spaces ds ON ix.data_space_id = ds.data_space_id
WHERE ix.NAME IS NOT NULL AND IIF(ix.type <= 2, ic.key_ordinal, ic.index_column_id) > 0
)
, Scrpt AS (
SELECT *
    , 'CREATE ' 
    + CASE WHEN is_unique = 1 THEN ' UNIQUE ' ELSE '' END 
    + type_desc COLLATE DATABASE_DEFAULT + ' INDEX ' + IndexName + ' ON ' 
        + SchemaName + '.' + TableName + '(' + KeyColumnsStr + ')' 
    + ISNULL(IIF(HasIncludedColumn > 0, ' ', ' INCLUDE (' + IncludedColumnsStr + ')'), '') 
    + IIF(filter_definition IS NULL, ' ', ' WHERE ' + filter_definition) 
    + ' WITH (' 
        + CASE WHEN IsColumnStore = 1 THEN ' DROP_EXISTING = OFF '
          ELSE
                IIF(is_padded = 1, ' PAD_INDEX = ON ', ' PAD_INDEX = OFF ') + ',' 
                + ' DROP_EXISTING = OFF ' + ',' 
                + ' ONLINE = OFF ' + ',' 
                + IIF(allow_row_locks = 1, ' ALLOW_ROW_LOCKS = ON ', ' ALLOW_ROW_LOCKS = OFF ') + ',' 
                + IIF(allow_page_locks = 1, ' ALLOW_PAGE_LOCKS = ON ', ' ALLOW_PAGE_LOCKS = OFF ') 
          END
        + ' ) ' 
    + IIF(DataSpaceType = 'FG','ON [' + DataSpaceName + ']', '') AS CreateIndexScript
FROM IndexInfo
)
SELECT DISTINCT IndexName, CreateIndexScript
FROM Scrpt
WHERE object_id = object_id('dbo.SWPartition')

为了感谢原作者,我在这里提到了原始链接 How to Generate Index Creation Scripts

【讨论】:

    【解决方案2】:

    列名存储在sys.columnssys.index_columns 表中。

    这将从所有表中选择列名:

    SELECT  sc.name
    FROM    sys.tables st
            INNER JOIN sys.columns sc ON sc.OBJECT_ID = st.OBJECT_ID
    WHERE   st.OBJECT_ID = 'ObjectID'
    

    或加入sys.indexes 表,这将选择表名和列:

    SELECT  st.name ,
            sc.name
    FROM    sys.indexes si
            INNER JOIN sys.tables st ON si.object_id = st.object_id
            INNER JOIN sys.columns sc ON sc.OBJECT_ID = st.OBJECT_ID
    

    您可以在语句中添加WHERE 子句以过滤您的索引列

    SELECT  si.name ,
            st.name ,
            sc.name
    FROM    sys.indexes si
            INNER JOIN sys.tables st ON si.object_id = st.object_id
            INNER JOIN sys.columns sc ON sc.OBJECT_ID = st.OBJECT_ID
    WHERE   si.name = 'IX_EVT_EVENTS'
    

    【讨论】:

    • 在什么方面可以将 sys.indexes 与 sys.columns 结合起来?
    • @ZhenyaShrub - 通过 object_id
    • 是的,但它会返回该表中的所有列,我只需要列作为我的键/索引
    • @ZhenyaShrub - 然后在您的键/索引上使用WHERE 子句进行过滤
    • 哦,我找不到从 sys.indexes 到列的任何引用
    猜你喜欢
    • 2023-03-11
    • 2012-02-23
    • 1970-01-01
    • 1970-01-01
    • 2020-04-09
    • 1970-01-01
    • 2017-05-24
    • 2011-06-17
    • 2013-05-09
    相关资源
    最近更新 更多