Как я могу отбросить все индексы в базе данных SQL одной командой?

Итак, как я могу удалить все индексы в базе данных SQL с помощью одной команды? У меня есть эта команда, которая получит мне все 20 или около того операторов отбрасывания, но как я могу запустить все эти операторы отбрасывания из этого "набор результатов "?

select * from vw_drop_idnex;

Еще один вариант, который дает мне тот же список:

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

Я пытался сделатьexec (выберите cmd из vw_drop_idnex) " и это нет работа. Я ищу что-то, что работает как цикл for и выполняет запросы один за другим.

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

С помощью Роба Фарли окончательный проект сценария:

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_key1 and index_id>0
for xml path(''));
exec sp_executesql @qry
 Rob Farley28 авг. 2009 г., 02:23
Я думаю это'Интересно, что вы добавили КАК QUERYLIST "когда на самом деле ответ вам нужен не долженне использовать это - как FOR XML PATH ('') лучше объединит строки в безымянные столбцы (т. е. без тегов).
 Rob Farley29 авг. 2009 г., 04:16
Круто - тыу нас это отсортировано. Я основывал свои материалы на вашем запросе sysindexes, так как большинство людей неу тебя есть копия твоегоvw_drop_idnex.

Ответы на вопрос(5)

Незначительные улучшения принятого ответа, которые я должен был сделать в моем собственном случае, в основном для учета схем:

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_key1 and index_id>0 and s.name'sys'
for xml path(''));
exec sp_executesql @qry

Также: в моем случае это не моглоне выполняется за один раз, потому что сценарий становится длиннее 4000 символов. Единственный способ, которым я мог придумать, - это поставитьтоп 20 " на внутреннем выберите и выполните его несколько раз.

 Ed Harper03 нояб. 2012 г., 19:22
Чтобы обойти ограничение количества символов, используйтеnvarchar(max) как тип данных для@qry если вы используете SQL 2005 или более позднюю версию.
 John04 нояб. 2012 г., 00:35
@EdHarper Я попробовал это, и он сказал мне, что тип может быть использован в качестве переменной. Я'м на 2008R2 (Экспресс).

От:Стивен Хиллс 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
 Wouter15 нояб. 2016 г., 17:53
Отлично! Он даже включает закомментированную строку печати для тестирования :)
 tigrou04 янв. 2018 г., 11:34
Это не удастся, если есть одно ограничение на таблицу, поскольку их можно удалить только с помощьюDROP CONSTRAINTнеDROP INDEX
Решение Вопроса

Вы'очень близко.

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
 djangofan28 авг. 2009 г., 02:24
большое спасибо! я знал об этом методе, но я надеялся на что-то, что не требовало объявления переменной. я могу заставить это работать хотя.
 WernerCD12 сент. 2013 г., 18:52
Учитывая, что это ~ 3 года спустя, я использовал это и исправил это, изменив выбор, как читать:SELECT 'DROP INDEX [' + ix.name + '] ON ' + OBJECT_NAME(ID) + '; ' - У меня есть индексы, которые включают+ знак и требует, чтобы фактическое имя индекса было разделено как[MY INDEX+], Другие символы и пробелы потребуют того же самого (возможно, вышеупомянутые
 djangofan28 авг. 2009 г., 02:32
вау, эта штука XML классная. ;-)
 djangofan28 авг. 2009 г., 02:34
это не совсем работает. я получаю сообщение: Msg 102, уровень 15, состояние 1, строка 1 Неверный синтаксис рядом с «<».
 Rob Kent23 июл. 2018 г., 16:23
Я использовал вышеуказанное решение, но оно удалило только четверть моих индексов. Решение здесь сработало лучше:mssqltips.com/sqlservertip/3441/...
 Rob Farley28 авг. 2009 г., 03:06
Звучит для меня как тыпытаемся назвать этот столбец еще. Убедитесь, что вы неестьКАК QUERYLIST " или что-нибудь там. Во время отладки замените строкуexec sp_executesql @qry " с "выберите @qry " чтобы увидеть, что тысобирается бежать. Это должно стать более очевидным.
 Rob Farley28 авг. 2009 г., 02:24
Также стоит упомянуть ... вы, вероятно, должны рассмотреть функцию quotename вокруг ваших имен, если в них есть пробелы.
 djangofan28 авг. 2009 г., 17:38
Если я вручную снимаю нарушающее ограничение, решение работает. Теперь мне просто нужно выяснить, как получить оператор ограничения удаления, который позволит мне удалять индексы.
 djangofan28 авг. 2009 г., 17:15
Ваш последний комментарий очень помог! проблема заключалась в том, что мне нужно было точку с запятой в конце каждого оператора SQL в наборе результатов. Кроме того, этот метод недайте мне соответствующий "изменить таблицу ... отказаться от контра ... запрос, который мне нужен для того, чтобы отбросить индексы. хранимая процедура vw_drop_idnex, которую я упоминал в начале моего вопроса, давала мне это. любая идея?

Мне нужен был тот, который также удалит индексы, которые резервируют уникальные или первичные ограничения (кроме случаев, когда они могут 'не будет сброшено, поскольку они резервируют внешний ключ)

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);

это сработало для меня, мы пропускаем системные индексы и для содержания

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_key1 and index_id>0
    and s.name!='sys' and s.name!='sys' and is_unique_constraint=0
for xml path(''));

exec sp_executesql @qry

Ваш ответ на вопрос