Как отбросить и воссоздать и индекс первичного ключа с помощью SMO с SQL Server?

Я использую Экспресс SQL Server 2005 года. Я хочу использовать SMO, чтобы циклично выполниться через каждую таблицу в базе данных и изменить каждый столбец Char на столбец Varchar. Если столбец является членом первичного ключа, я должен сначала отбросить первичный ключ прежде, чем изменить тип данных столбца. Затем я должен воссоздать индекс. Вот код, который я пытаюсь использовать:

foreach (Table table in database.Tables)
{
    Index pk = table.Indexes.Cast<Index>().SingleOrDefault(index => index.IndexKeyType == IndexKeyType.DriPrimaryKey);
    if (pk != null)
    {
        pk.Drop();
        table.Alter();
    }
    foreach (Column column in table.Columns.Cast<Column>().Where(column => column.DataType.SqlDataType == SqlDataType.Char))
    {
        column.DataType = new DataType(SqlDataType.VarChar, column.DataType.MaximumLength);
    }
    table.Alter();
    if (pk != null)
    {
        pk.Create();
    }
}

Но когда я пытаюсь создать индекс, я добираюсь, исключение с сообщением "Не может получить доступ к свойствам или методам для Microsoft. SqlServer. Управление. Smo. Индекс ' [PK_table1] ', потому что это было отброшено". Так есть ли хороший способ выполнить то, что я хочу сделать с SMO?

Я пытался писать сценарий индекса, прежде чем я отбросил его с помощью метода Сценария Индекса, но он выдает исключение с сообщением "Индексные 'PK_table1' ссылки несуществующий столбец' [table1]. [владелец]'". Столбец владельца ясно существует.

7
задан YWE 11 August 2010 в 21:23
поделиться

5 ответов

Возможно, объект индекса потерял ссылку на таблицу. Вы пытались добавить индекс обратно к объекту таблицы?

table.Indexes.Add(pk);
0
ответ дан 7 December 2019 в 03:09
поделиться

Попробуйте еще раз создать первичный ключ следующим образом.

Index index = new Index(table, "PK_tableNameTable");
index.IndexKeyType = IndexKeyType.DriPrimaryKey;

//You will have to store the names of columns before deleting the key.
index.IndexedColumns.Add(new IndexedColumn(index,"ID")); 

table.Indexes.Add(index);

Источник фрагмента

4
ответ дан 7 December 2019 в 03:09
поделиться

Есть ли у вас возможность запускать сценарии SQL через SMO? Я начал запускать все скрипты, которые вносят какие-либо структурные изменения в БД, через ServerConnection.ExecuteNonQuery. Большое улучшение стабильности по сравнению с обычным стеком SqlCommand и т. Д. (Тоже не идет вразрез с GO :-) В итоге получилось очень полезное слияние. Разумеется, не-MARS соединение.

0
ответ дан 7 December 2019 в 03:09
поделиться

Вместо того чтобы удалять и воссоздавать индекс, попробуйте просто отключить его, а затем снова включить, когда закончите, используя методы .Disable и .Enable.

0
ответ дан 7 December 2019 в 03:09
поделиться

Мне удалось удалить первичный ключ, изменить типы данных столбца и воссоздать первичный ключ с помощью этого кода:

// using System.Collections.Specialized;

foreach (Table table in database.Tables)
{
    // object to hold the index script
    StringCollection pk_script = new StringCollection();

    Index pk = table.Indexes.Cast<Index>().SingleOrDefault(index => index.IndexKeyType == IndexKeyType.DriPrimaryKey);
    if (pk != null)
    {
        // script the index
        pk_script = pk.Script();
        pk.Drop();
        table.Alter();
    }
    foreach (Column column in table.Columns.Cast<Column>().Where(column => column.DataType.SqlDataType == SqlDataType.Char))
    {
        column.DataType = new DataType(SqlDataType.VarChar, column.DataType.MaximumLength);
    }
    table.Alter();

    // iterate through script StringCollection
    foreach (String tsql in pk_script)
    {
        database.ExecuteNonQuery(tsql);
    }                
} 

Некоторые предостережения:

  1. Строка, которая определяет pk бросит исключение, если есть таблица без индексов
  2. Удаление первичного ключа не удастся если на таблицу ссылается представление, привязанное к схеме
  3. Удаление первичного ключа не удастся если на таблицу ссылается ограничения внешнего ключа
  4. Изменение типа данных столбца потерпит неудачу, если этот столбец используется в некластеризованный индекс
  5. Если у вас очень большая таблица, удаление кластерного первичного ключа преобразует таблицу в кучу. Время, необходимое для удаления кластерный индекс предложит процесс не удался (в то время как, по сути, он все еще работает)
  6. Предположительно, вам понадобится код для очистите StringCollection после индексный скрипт был выполнен
5
ответ дан 7 December 2019 в 03:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: