web-dev-qa-db-fra.com

Comment puis-je supprimer tous les index d'une base de données SQL avec une seule commande?

Alors, comment puis-je supprimer tous les index d'une base de données SQL avec une seule commande? J'ai cette commande qui va me procurer une vingtaine d'instructions drop, mais comment puis-je toutes les exécuter à partir de cet "ensemble de résultats"?

select * from vw_drop_idnex;

Une autre variante qui me donne la même liste est la suivante:

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_%'

J'ai essayé de faire "exec (sélectionnez cmd de vw_drop_idnex)" et cela n'a pas fonctionné. Je recherche quelque chose qui fonctionne comme une boucle for et exécute les requêtes une à une.

-----------------------

Avec l'aide de Rob Farleys, la version finale du script est la suivante:

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
17
djangofan

Tu es très proche.

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
25
Rob Farley

cela a fonctionné pour moi nous sautons les index système et pour 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
6
zxxc

De: Stephen Hill's 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
5
Tawani

Améliorations mineures apportées à la réponse acceptée que je devais apporter dans mon propre cas, principalement pour rendre compte de schémas:

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

Aussi: dans mon cas, il ne pouvait pas être exécuté en une fois, car le script contenait plus de 4 000 caractères. La seule façon dont je pouvais penser à cela était de placer un "top 20" sur la sélection interne et de l'exécuter plusieurs fois.

1
John

Aucune des réponses ne correspondait vraiment à mes besoins. 

J'avais besoin d'un outil qui supprime également les index sauvegardant les contraintes uniques ou principales (sauf si elles ne peuvent pas être supprimées car elles sauvegardent une clé étrangère)

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);
0
Martin Smith