删除索引,如果名称

时间:2016-03-03 21:11:29

标签: sql sql-server

我想找到一种方法,在SQL Server中使用单个查询从各个表中删除多个索引。我可以通过下面的查询找到索引名称和表格,但是我对如何删除它找到的表格感到有点迷失。

SELECT
            so.name AS TableName
            , si.name AS IndexName
            , si.type_desc AS IndexType
FROM
            sys.indexes si
            JOIN sys.objects so ON si.[object_id] = so.[object_id]
WHERE
            so.type = 'U'    --Only get indexes for User Created Tables
            AND si.name IS NOT NULL
            and si.name like 'NCI%'
ORDER BY
            so.name, si.type 

3 个答案:

答案 0 :(得分:5)

您可以从SELECT

开始构建drop脚本
DECLARE @SQL NVARCHAR(MAX) = N''

SELECT @SQL = @SQL + 'DROP INDEX ' + so.name + '.' + si.name + ';' + CHAR(13) + CHAR(10)
FROM
            sys.indexes si
            JOIN sys.objects so ON si.[object_id] = so.[object_id]
WHERE
            so.type = 'U'    --Only get indexes for User Created Tables
            AND si.name IS NOT NULL
            and si.name like '%%'
ORDER BY
            so.name, si.type 

PRINT @SQL
EXEC (@SQL)

@SQL以增量方式构建,并包含由DROP分隔的所有;语句,以便它们在单个批处理中执行。 DROP表可以以类似的方式完成。

注意:您的查询还会捕获与PK关联的索引,并且不能直接删除它们,因为它们会被约束加倍(PK =约束+索引)

答案 1 :(得分:2)

这是生活中你通常会想要使用光标的时间之一,因为你的陈述是动态的。

DECLARE drop_cur cursor for 
SELECT
            QUOTENAME(so.name) AS TableName,
            QUOTENAME(si.name) AS IndexName,
            si.type_desc AS IndexType
FROM
            sys.indexes si
            JOIN sys.objects so ON si.[object_id] = so.[object_id]
WHERE
            so.type = 'U'    --Only get indexes for User Created Tables
            AND si.name IS NOT NULL
            and si.name like 'NCI%'
ORDER BY
            so.name, si.type 

OPEN drop_cur
DECLARE @tablename NVARCHAR(MAX), @indexname NVARCHAR(MAX), @indextype NVARCHAR(MAX);

FETCH NEXT FROM drop_cur INTO @tableName, @indexName, @indextype
WHILE @@fetch_status = 0 BEGIN    
    DECLARE @dropSql NVARCHAR(MAX) = 'drop index ' + @tablename + '.' + @indexname
    PRINT @dropSql
    --EXEC sp_executesql @dropSql --Uncomment to perform the drop.
    FETCH NEXT FROM drop_cur INTO @tableName, @indexName, @indextype
END 

CLOSE drop_cur
DEALLOCATE drop_cur

答案 2 :(得分:0)

declare @tabName sysname
declare @ixName sysname
declare @sql varchar(1000)  --Probably don't need it, but meh.

declare cur_dels cursor for
SELECT
            so.name AS TableName
            , si.name AS IndexName
--            , si.type_desc AS IndexType
FROM
            sys.indexes si
            JOIN sys.objects so ON si.[object_id] = so.[object_id]
WHERE
            so.type = 'U'    --Only get indexes for User Created Tables
            AND si.name IS NOT NULL
            and si.name like 'NCI%'
ORDER BY
            so.name, si.type 

open cur_dels
fetch next from cur_dels into @tabName, @ixName

while @@fetch_status = 0
    begin
        set @sql = 'alter table ' + @tabName + ' drop ' + @ixName + ';'
        print @sql
        --exec sp_executesql @sql
        fetch next from cur_dels into @tabName, @ixName
    end

close cur_dels
deallocate cur_dels

显然,如果你想在没有看到发生了什么的情况下运行它,请取消循环中的exec语句&删除打印声明。如果你想查看它(虽然......好吧,我会做,而不是让它自由),请保持原样。