So, how can I drop all indexes in a SQL database with one command? I have this command that will get me all the 20 or so drop statements, but how can I run all of those drop statements from this "result set"?
那么,如何使用一个命令删除SQL数据库中的所有索引?我有这个命令,可以得到大约20个drop语句,但是我如何从这个“result set”中运行所有这些drop语句呢?
select * from vw_drop_idnex;
Another variation that gives me the same list is:
另一个给我相同列表的变化是:
SELECT 'DROP INDEX ' + ix.Name + ' ON ' + OBJECT_NAME(ID) AS QUERYLIST
FROM sysindexes ix
WHERE ix.Name IS NOT null and ix.Name like '%pre_%'
I tried to do "exec(select cmd from vw_drop_idnex)" and it didn't work. I am looking for something that works like a for loop and runs the queries one by one.
我尝试执行“exec(从vw_drop_idnex中选择cmd)”,但它不起作用。我正在寻找一个像for循环一样工作并逐一运行查询的东西。
-----------------------
With Rob Farleys help, final draft of the script is:
在Rob farley的帮助下,剧本的最终草稿是:
declare @ltr nvarchar(1024);
SELECT @ltr = ( select 'alter table '+o.name+' drop constraint '+i.name+';'
from sys.indexes i join sys.objects o on i.object_id=o.object_id
where o.type<>'S' and is_primary_key=1
FOR xml path('') );
exec sp_executesql @ltr;
declare @qry nvarchar(1024);
select @qry = (select 'drop index '+o.name+'.'+i.name+';'
from sys.indexes i join sys.objects o on i.object_id=o.object_id
where o.type<>'S' and is_primary_key<>1 and index_id>0
for xml path(''));
exec sp_executesql @qry
5 个解决方案
#1
24
You're very close.
你非常接近。
declare @qry nvarchar(max);
select @qry =
(SELECT 'DROP INDEX ' + ix.name + ' ON ' + OBJECT_NAME(ID) + '; '
FROM sysindexes ix
WHERE ix.Name IS NOT null and ix.Name like '%prefix_%'
for xml path(''));
exec sp_executesql @qry
#2
5
From: Stephen Hill's Bloggie
来自:斯蒂芬·希尔的Bloggie
DECLARE @indexName VARCHAR(128)
DECLARE @tableName VARCHAR(128)
DECLARE [indexes] CURSOR FOR
SELECT [sysindexes].[name] AS [Index],
[sysobjects].[name] AS [Table]
FROM [sysindexes]
INNER JOIN [sysobjects]
ON [sysindexes].[id] = [sysobjects].[id]
WHERE [sysindexes].[name] IS NOT NULL
AND [sysobjects].[type] = 'U'
--AND [sysindexes].[indid] > 1
OPEN [indexes]
FETCH NEXT FROM [indexes] INTO @indexName, @tableName
WHILE @@FETCH_STATUS = 0
BEGIN
--PRINT 'DROP INDEX [' + @indexName + '] ON [' + @tableName + ']'
Exec ('DROP INDEX [' + @indexName + '] ON [' + @tableName + ']')
FETCH NEXT FROM [indexes] INTO @indexName, @tableName
END
CLOSE [indexes]
DEALLOCATE [indexes]
GO
#3
5
this worked for me we skip sys indexes and for constaints
这对我有用,我们跳过系统索引和检查
declare @qry nvarchar(max);
select @qry = (
select 'IF EXISTS(SELECT * FROM sys.indexes WHERE name='''+ i.name +''' AND object_id = OBJECT_ID(''['+s.name+'].['+o.name+']'')) drop index ['+i.name+'] ON ['+s.name+'].['+o.name+']; '
from sys.indexes i
inner join sys.objects o on i.object_id=o.object_id
inner join sys.schemas s on o.schema_id = s.schema_id
where o.type<>'S' and is_primary_key<>1 and index_id>0
and s.name!='sys' and s.name!='sys' and is_unique_constraint=0
for xml path(''));
exec sp_executesql @qry
#4
1
Minor improvements to the accepted answer that I had to make in my own case, mostly to account for schemas:
在我自己的情况下,我必须对已被接受的答案做一些小的改进,主要是为了说明模式:
declare @qry nvarchar(4000);
select @qry = (select 'drop index ['+s.name+'].['+o.name+'].['+i.name+'];'
from sys.indexes i join sys.objects o on i.object_id=o.object_id join sys.schemas s on o.schema_id=s.schema_id
where o.type<>'S' and is_primary_key<>1 and index_id>0 and s.name<>'sys'
for xml path(''));
exec sp_executesql @qry
Also: In my case it couldn't run in one go because the script becomes longer than 4000 characters. The only way I could think of to deal with that was to put a "top 20" on the inner select and execute it multiple times.
同样:在我的例子中,它不能一次运行,因为脚本变得超过4000个字符。我能想到的解决这个问题的唯一办法就是在内部选择中加入“前20名”,并多次执行。
#5
0
None of the answers quite suited my needs.
这些答案都不太符合我的需要。
I needed one that will also drop indexes that backup unique or primary constraints (except if these can't be dropped as they back up a foreign key)
我需要一个也将删除备份惟一或主约束的索引(除非这些索引在备份外键时不能删除)
DECLARE @SqlScript NVARCHAR(MAX);
SELECT @SqlScript =
(
SELECT
'
BEGIN TRY
'+ CASE WHEN 1 IN (i.is_primary_key, i.is_unique_constraint) THEN
'
ALTER TABLE ' + QUOTENAME(OBJECT_SCHEMA_NAME(i.object_id)) + '.' + QUOTENAME(t.name) + ' DROP CONSTRAINT ' + QUOTENAME(i.name) + ';'
else
'
DROP INDEX ' + QUOTENAME(i.name) + ' ON ' + QUOTENAME(OBJECT_SCHEMA_NAME(i.object_id)) + '.' + QUOTENAME(t.name)
END+'
END TRY
BEGIN CATCH
RAISERROR(''Could not drop %s on table %s'', 0,1, ' + QUOTENAME(i.name, '''') + ', ' + QUOTENAME(t.name, '''') + ')
END CATCH
'
FROM sys.indexes i
JOIN sys.tables t ON i.object_id = t.object_id
WHERE i.type_desc IN ('CLUSTERED', 'NONCLUSTERED' )
ORDER BY t.object_id, i.index_id DESC
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)');
--Return script that will be run
SELECT @SqlScript AS [processing-instruction(x)]
FOR XML PATH('');
EXEC (@SqlScript);
#1
24
You're very close.
你非常接近。
declare @qry nvarchar(max);
select @qry =
(SELECT 'DROP INDEX ' + ix.name + ' ON ' + OBJECT_NAME(ID) + '; '
FROM sysindexes ix
WHERE ix.Name IS NOT null and ix.Name like '%prefix_%'
for xml path(''));
exec sp_executesql @qry
#2
5
From: Stephen Hill's Bloggie
来自:斯蒂芬·希尔的Bloggie
DECLARE @indexName VARCHAR(128)
DECLARE @tableName VARCHAR(128)
DECLARE [indexes] CURSOR FOR
SELECT [sysindexes].[name] AS [Index],
[sysobjects].[name] AS [Table]
FROM [sysindexes]
INNER JOIN [sysobjects]
ON [sysindexes].[id] = [sysobjects].[id]
WHERE [sysindexes].[name] IS NOT NULL
AND [sysobjects].[type] = 'U'
--AND [sysindexes].[indid] > 1
OPEN [indexes]
FETCH NEXT FROM [indexes] INTO @indexName, @tableName
WHILE @@FETCH_STATUS = 0
BEGIN
--PRINT 'DROP INDEX [' + @indexName + '] ON [' + @tableName + ']'
Exec ('DROP INDEX [' + @indexName + '] ON [' + @tableName + ']')
FETCH NEXT FROM [indexes] INTO @indexName, @tableName
END
CLOSE [indexes]
DEALLOCATE [indexes]
GO
#3
5
this worked for me we skip sys indexes and for constaints
这对我有用,我们跳过系统索引和检查
declare @qry nvarchar(max);
select @qry = (
select 'IF EXISTS(SELECT * FROM sys.indexes WHERE name='''+ i.name +''' AND object_id = OBJECT_ID(''['+s.name+'].['+o.name+']'')) drop index ['+i.name+'] ON ['+s.name+'].['+o.name+']; '
from sys.indexes i
inner join sys.objects o on i.object_id=o.object_id
inner join sys.schemas s on o.schema_id = s.schema_id
where o.type<>'S' and is_primary_key<>1 and index_id>0
and s.name!='sys' and s.name!='sys' and is_unique_constraint=0
for xml path(''));
exec sp_executesql @qry
#4
1
Minor improvements to the accepted answer that I had to make in my own case, mostly to account for schemas:
在我自己的情况下,我必须对已被接受的答案做一些小的改进,主要是为了说明模式:
declare @qry nvarchar(4000);
select @qry = (select 'drop index ['+s.name+'].['+o.name+'].['+i.name+'];'
from sys.indexes i join sys.objects o on i.object_id=o.object_id join sys.schemas s on o.schema_id=s.schema_id
where o.type<>'S' and is_primary_key<>1 and index_id>0 and s.name<>'sys'
for xml path(''));
exec sp_executesql @qry
Also: In my case it couldn't run in one go because the script becomes longer than 4000 characters. The only way I could think of to deal with that was to put a "top 20" on the inner select and execute it multiple times.
同样:在我的例子中,它不能一次运行,因为脚本变得超过4000个字符。我能想到的解决这个问题的唯一办法就是在内部选择中加入“前20名”,并多次执行。
#5
0
None of the answers quite suited my needs.
这些答案都不太符合我的需要。
I needed one that will also drop indexes that backup unique or primary constraints (except if these can't be dropped as they back up a foreign key)
我需要一个也将删除备份惟一或主约束的索引(除非这些索引在备份外键时不能删除)
DECLARE @SqlScript NVARCHAR(MAX);
SELECT @SqlScript =
(
SELECT
'
BEGIN TRY
'+ CASE WHEN 1 IN (i.is_primary_key, i.is_unique_constraint) THEN
'
ALTER TABLE ' + QUOTENAME(OBJECT_SCHEMA_NAME(i.object_id)) + '.' + QUOTENAME(t.name) + ' DROP CONSTRAINT ' + QUOTENAME(i.name) + ';'
else
'
DROP INDEX ' + QUOTENAME(i.name) + ' ON ' + QUOTENAME(OBJECT_SCHEMA_NAME(i.object_id)) + '.' + QUOTENAME(t.name)
END+'
END TRY
BEGIN CATCH
RAISERROR(''Could not drop %s on table %s'', 0,1, ' + QUOTENAME(i.name, '''') + ', ' + QUOTENAME(t.name, '''') + ')
END CATCH
'
FROM sys.indexes i
JOIN sys.tables t ON i.object_id = t.object_id
WHERE i.type_desc IN ('CLUSTERED', 'NONCLUSTERED' )
ORDER BY t.object_id, i.index_id DESC
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)');
--Return script that will be run
SELECT @SqlScript AS [processing-instruction(x)]
FOR XML PATH('');
EXEC (@SqlScript);