2013-07-05 2 views
6

У меня ситуация в моем SQL Server 2008.падения SQL Server и воссоздают индексы таблицы

мне нужно изменить тип столбца, а индексы предотвращение изменения. Но из-за того, что база данных находится на нескольких клиентах, я не знаю, сколько индексов существует с использованием столбца.

Есть какой-либо способ получить, программно говоря, все индексы, которые включают столбец и отбрасывать их, и после того, как оператор alter table заново создаст их автоматически?

Я слышал, что отключить их кулак с таблицей, потому что это изменение типа.

Я перехожу от tinyint к небольшому типу.

+0

Нет прямого пути к DROP и воссозданию индексов. Вы можете выполнить сценарий всех необходимых индексов перед удалением. После того как вы изменили типы данных, вы можете использовать эти сценарии CREATE для воссоздания индексов. –

+0

Я привел пример кода о том, как это сделать здесь. Https://stackoverflow.com/a/46335197/1878141 –

ответ

4

DISABLE все индексы таблицы назначения

ALTER INDEX Indexname ON Table DISABLE 

Затем Alter тип данных столбца

ALTER TABLE table 
ALTER COLUMN columnname datatype 

После этого Включить индексы

ALTER INDEX Indexname ON Table REBUILD 
+0

Это будет работать, если вам не нужно отключать кластеризованный индекс. Если этот индекс отключен, вы получите сообщение об ошибке: «Не удается выполнить указанную операцию в теге« test », потому что его кластеризованный индекс« ix_test »отключен». –

+0

Проблема в том, что я не знаю имена индексов или кластеризован или нет. Клиенты могут самостоятельно изменять. – Rafael

+0

Вы можете найти через EXEC sp_helpindex 'tablename' –

2

Вы можете использовать ниже скрипт, который возвращает указатель имен и Тип для указанной таблицы/колонки:

DECLARE @tableName SYSNAME 
DECLARE @columnName SYSNAME 

SET @tableName = 'Products' 
SET @columnName = 'Name' 

SELECT IDX.name, IDX.type_desc, IndexedColumn 
FROM sys.tables TBL 
INNER JOIN sys.indexes IDX ON TBL.object_id = IDX.object_id 
LEFT JOIN sys.filegroups FG ON IDX.data_space_id = FG.data_space_id 
CROSS APPLY 
( SELECT COLS.Name 
    FROM sys.index_columns IXCL 
    INNER JOIN sys.columns COLS 
       ON IXCL.object_id = COLS.object_id 
       AND IXCL.column_id = COLS.column_id 
    WHERE IDX.object_id = IXCL.object_id 
    AND  IDX.index_id = IXCL.index_id 
    AND  COLS.name = @columnName 
    AND  IDX.object_id = OBJECT_ID(@tableName) 
) Indexed (IndexedColumn) 
WHERE TBL.object_id = OBJECT_ID(@tableName) 

Надежда Это помогает ...

+0

Спасибо за помощь Vishal, я сделаю небольшую программу для обновления базы данных с помощью помощи, которую вы мне дали. – Rafael

3

Также попробуйте это знать все индексы таблицы с именами столбцов:

SELECT OBJECT_SCHEMA_NAME(ind.object_id) AS SchemaName 
     , OBJECT_NAME(ind.object_id) AS ObjectName 
     , ind.name AS IndexName 
     , ind.is_primary_key AS IsPrimaryKey 
     , ind.is_unique AS IsUniqueIndex 
     , col.name AS ColumnName 
     , ic.is_included_column AS IsIncludedColumn 
     , ic.key_ordinal AS ColumnOrder 
FROM sys.indexes ind 
     INNER JOIN sys.index_columns ic 
      ON ind.object_id = ic.object_id 
       AND ind.index_id = ic.index_id 
     INNER JOIN sys.columns col 
      ON ic.object_id = col.object_id 
       AND ic.column_id = col.column_id 
     INNER JOIN sys.tables t 
      ON ind.object_id = t.object_id 
WHERE t.is_ms_shipped = 0 
ORDER BY OBJECT_SCHEMA_NAME(ind.object_id) --SchemaName 
     , OBJECT_NAME(ind.object_id) --ObjectName 
     , ind.is_primary_key DESC 
     , ind.is_unique DESC 
     , ind.name --IndexName 
     , ic.key_ordinal 
+0

Спасибо за помощь @ Гайтри, я сделаю небольшую программу для обновления базы данных с помощью помощи, которую вы мне дали. – Rafael

0

Давайте предположим, что основной случай (столбец не является частью какой-либо ограничение, а не столбец XML, имеющий индекс XML над ним, и т.д.), то можно сделать следующее:

  • генерировать описание индексов как XML с использованием select (...) from <sys.indexes + other sys schema views> FOR XML ...
  • помещает каждый XML в качестве расширенного свойства таблицы, называя его, например. с префиксом 'IX_' ('IX_1', 'IX_2', и т.д. ...)
  • падение индексов
  • изменяющие столбец
  • собрать все расширенные свойства таблицы, имеющей префикс 'IX_'
  • воссоздают каждый индекс основан на его описании XML
0

Вы можете использовать встроенные инструменты для выполнения этой работы. В SQL Server Management Studio нажмите «Инструменты», затем «Параметры»

Разверните «Обозреватель объектов SQL Server» и в нем выберите «Сценарии».

Прокрутите вниз до пункта «Таблица и вид» справа.

Найдите запись под названием «Индексы скриптов» и установите ее «Истина», затем нажмите «ОК».

Когда вы щелкните правой кнопкой мыши на своей таблице в Обозревателе объектов, у вас есть опции «Script As ...«выбор любого из этих параметров теперь будет выполнять скрипты с индексами, а также с самой таблицей и ее ключами. Скопируйте требуемые сценарии или просто запустите все это в зависимости от ваших потребностей.

0

Вот пример SQL drop и воссоздавая индекс безопасно:

IF(select object_id from sys.indexes where [name] = 'IDX_RecordSubscription' and object_id = OBJECT_ID('[SystemSetup].[RecordSubscription]')) IS NOT NULL 
BEGIN 
    DROP INDEX [SystemSetup].[RecordSubscription].IDX_RecordSubscription 
END 

GO 

CREATE UNIQUE INDEX 
    IDX_RecordSubscription 
ON 
    [SystemSetup].[RecordSubscription] 
    (
      Subscriber ASC, 
    MenuItem ASC, 
    RecordPrimaryKeyGuid ASC 

    ) 
    WITH 
    (
     PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = OFF 
    ) ON [PRIMARY] 

GO 

Вот некоторые C# код, который качает это:

protected override string GetCreateIndexScript(string uniquePart, string indexName, string fullTableName, string columnsPart) 
    { 
     return 
      $"IF(select object_id from sys.indexes where [name] = '{indexName}' and object_id = OBJECT_ID('{fullTableName}')) IS NOT NULL \r\n" + 
      "BEGIN \r\n" + 
      $" DROP INDEX {fullTableName}.{indexName} \r\n " + 
      "END\r\n\r\n" + 
      "GO\r\n\r\n" + 
      $"CREATE {uniquePart} INDEX\r\n" + 
      $"\t{indexName}\r\n" + 
      "ON\r\n" + 
      $"\t{fullTableName}\r\n" + 
      "\t(\r\n" + 
      $"\t\t{columnsPart}\r\n" + 
      "\t)\r\n" + 
      "\tWITH\r\n" + 
      "\t(\r\n" + 
      "\t\tPAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = OFF\r\n" + 
      "\t) ON [PRIMARY] "; 
    } 

Вот некоторые C# (которые могут быть преобразованы в SQL), чтобы получить индекс схемы:

  const string selectStatement = "select " + 
              " SCHEMAs.name + '.' + tabs.name as OBJECT_ID, " + 
              " ind.name as INDEX_NAME, " + 
              " indcol.index_id AS INDEX_ID, " + 
              " indcol.key_ordinal AS COLUMN_ORDINAL, " + 
              " col.name AS COLUMN_NAME, " + 
              " ind.is_unique " + 
              "from " + 
              " sys.indexes ind " + 
              "inner join " + 
              " sys.index_columns indcol  " + 
              "on " + 
              " ind.object_id = indcol.object_id and " + 
              " ind.index_id = indcol.index_id " + 
              "inner join " + 
              " sys.columns col " + 
              "on " + 
              " col.object_id = indcol.object_id and " + 
              " col.column_id = indcol.column_id " + 
              "inner join " + 
              " sys.tables tabs " + 
              "on " + 
              " tabs.object_id = ind.object_id " + 
              "inner join " + 
              " sys.schemas schemas " + 
              "on " + 
              " tabs.schema_id = schemas.schema_id " + 
              "where " + 
              " ind.type =2 and" + 
              " tabs.name <> 'sysdiagrams' " + 
              "order by " + 
              " tabs.object_id, " + 
              " indcol.index_id, " + 
              " indcol.key_ordinal "; 

      return DatabaseAdapter.Fill(selectStatement, null, null, null); 

Итак, в основном, вы выполняете последний фрагмент кода, итерации по результатам (индексы и столбцы) и вызываете GetCreateIndexScript для каждого возвращаемого индекса. Затем вы можете безопасно выполнять каждое из созданных инструкций для сброса и воссоздания индексов.

Этот же подход можно использовать с TSQL или другим языком.

Смежные вопросы