2013-07-05 15 views
6

Mam sytuacji w moim SQL Server 2008.drop SQL Server i ponownie indeksy tabeli

Muszę zmienić typ kolumny, ale indeksy są zapobieganie zmianom. Ale ponieważ baza danych znajduje się na kilku klientach, nie wiem, ile istnieje indeksów dotyczących kolumny.

Istnieje sposób na uzyskanie, programowo, wszystkich indeksów, które obejmują kolumnę i upuść je, a po oświadczeniu alter table odtworzyć je automatycznie?

Słyszałem, że wyłączenie ich bałagan kamery ze stołem, ponieważ zmiana typu.

Zmieniam się z tinyint na smallint type.

+0

Nie ma bezpośredniego sposobu na upuszczenie i ponowne utworzenie indeksów. Możesz skrypty wszystkich wymaganych indeksów przed upuszczeniem. Po zmianie typów danych można użyć tych skryptów CREATE do odtworzenia indeksów. –

+0

Podałem przykładowy kod, jak to zrobić tutaj https://stackoverflow.com/a/46335197/1878141 –

Odpowiedz

4

wyłączyć wszystkie indeksy tabeli docelowej

ALTER INDEX Indexname ON Table DISABLE 

Następnie zmień typ danych kolumny

ALTER TABLE table 
ALTER COLUMN columnname datatype 

Potem Włącz indeksów

ALTER INDEX Indexname ON Table REBUILD 
+0

To będzie działać, chyba że musisz wyłączyć indeks klastrowany. Jeśli ten indeks jest wyłączony, pojawi się błąd: "Nie można wykonać określonej operacji w tabeli" test ", ponieważ jej indeks klastrowy" ix_test "jest wyłączony." –

+0

Problem polega na tym, że nie znam nazw indeksów lub jeśli jest klastrowany lub nie. Klienci mogą modyfikować samodzielnie. – Rafael

+0

Możesz dowiedzieć się przez EXEC sp_helpindex "nazwa_tabeli" –

2

Możesz skorzystać z poniższego skryptu, która zwraca nazwę indeksu i Typ dla określonej tabeli/kolumny:

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) 

Nadzieja Pomaga to ...

+0

Dzięki za pomoc, Vishal, zrobię mały program do aktualizacji bazy danych za pomocą pomocy, którą mi daliście. – Rafael

3

Sponsorowane to znać wszystkie indeksy w tabeli z nazwami kolumn:

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

Dzięki za pomoc @Gayathri, zrobię mały program do aktualizacji bazy danych za pomocą pomocy, którą mi daliście. – Rafael

0

Załóżmy podstawowe sprawy (kolumna nie jest częścią ograniczenie nie kolumnie XML mający wskaźnik XML nad nim, etc.), dodaje się może być wykonane:

  • generowania indeksy określeń XML stosując select (...) from <sys.indexes + other sys schema views> FOR XML ...
  • umieszczają każdy plik XML jako rozszerzoną właściwość tabeli nazywającej ją np. z przedrostkiem 'IX_' ('IX_1', 'IX_2', itp ...)
  • spadek indeksy
  • zmieniają kolumna
  • zebrać wszystkie przedłużone właściwości tabeli mające przedrostek 'IX_'
  • odtworzyć każdy indeks oparty na jego opisie XML
0

Możesz użyć wbudowanych narzędzi do wykonania tego zadania. W SQL Server Management Studio, kliknij "Narzędzia", ​​następnie "Opcje"

Rozwiń "SQL Server Object Explorer" i wewnątrz niego kliknij "Skrypty".

Przewiń w dół do "Tabeli i opcji widoku" po prawej stronie.

Znajdź rekord o nazwie "Indeksy skryptów" i ustaw go na "True", a następnie kliknij przycisk OK.

Po kliknięciu prawym przyciskiem myszy na stole w Eksploratorze obiektów dostępne są opcje "Skryptuj jako ..."wybranie którejkolwiek z tych opcji spowoduje teraz utworzenie skryptu indeksów, a także samej tabeli i jej kluczy, skopiuj wymagane skrypty lub po prostu uruchom wszystko w zależności od potrzeb:

0

Oto przykładowy kod SQL upuszczania i odtwarzając indeks bezpiecznie:

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 

Oto kod C#, że pompy to uwagę:

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] "; 
    } 

Oto niektóre C# (które mogą być konwertowane do SQL), aby uzyskać schemat index:

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

Zasadniczo, wykonujesz tutaj ostatni fragment kodu, przeglądasz wyniki (indeksy i kolumny) i wywołujesz GetCreateIndexScript dla każdego zwracanego indeksu. Następnie można bezpiecznie wykonać każdą z instrukcji, które zostały utworzone w celu upuszczenia i ponownego utworzenia indeksów.

To samo podejście można zastosować w przypadku języka TSQL lub innego języka.