Отбрасывание ограничения (индекса) на столбце

12

Как я могу изменить тип таблицы с индексом? Я попытался сделать столбец alter для пустой таблицы, чтобы изменить тип с даты на varchar (15), и получил сообщения о том, что у него есть зависимости от столбца (который оказался индексами).

Я смог легко обойти это локально, щелкнув правой кнопкой мыши по индексу и написав сценарий для удаления, но мне нужно развернуть его на других серверах, где у меня не будет доступа к имени индекса.

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

user1480
источник

Ответы:

7

Вы можете использовать представление sys.indexes для получения индексов. Вы можете присоединить эту таблицу к sys.tables, sys.columns и sys.index_column, чтобы получить информацию для создания динамического индекса удаления. Вы можете использовать этот простой выбор, чтобы создать свой индекс выпадения. Вы можете использовать предложение where для фильтрации таблиц и столбцов. Если вы хотите изменить Table1.Column1, вы должны использовать это имя для фильтрации выбора, чтобы получить правильный оператор удаления

use [testdb]
go
declare @sqlDropIndex NVARCHAR(1000)

select @sqlDropIndex = 'DROP INDEX ' + idx.name + ' ON ' + tbl.name
from sys.indexes idx inner join 
        sys.tables tbl on idx.object_id = tbl.object_id inner join
        sys.index_columns idxCol on idx.index_id = idxCol.index_id inner join
        sys.columns col on idxCol.column_id = col.column_id
where idx.type <> 0 and
        tbl.name = 'MyTableName' and
        col.name = 'MyColumnName'
group by idx.name, tbl.name
order by idx.name desc

print @sqlDropIndex
--exec sp_executeSql @sqlDropIndex
go

Надеюсь, что это поможет вам

Нико
источник
3
при присоединении вы должны обогатить операторы объединения с помощью idx.object_id = idxCol.object_id & idxCol.object_id = col.object_id, и нет необходимости в группировке.
Бакс
2

Чтобы изменить любой столбец, сначала необходимо удалить индекс или любые другие ограничения, содержащие этот столбец, а затем снова создать индекс / ограничение. Но эта задача должна выполняться администратором базы данных, потому что любое падение индекса или ограничения будет влиять, с одной стороны, на запрашиваемые данные - в то время как индекс удаляется, а с другой стороны, наложить блокировку на всю таблицу на время восстановления индекса. создано. Вы должны убедиться, что пользователи будут знать об этом небольшом или большом (зависит от размера таблицы) обслуживании. Удачи!

Однако создание индекса может быть выполнено с опцией Online, которая меньше блокирует.

yrushka
источник
0

Если вы сначала удалите индекс, вы не сможете читать его снова, пока индекс не будет создан заново. Что вы можете сделать, чтобы отключить применение ограничения.

ALTER TABLE name_of_the_table NOCHECK CONSTRAINT name_of_the_constraint;

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

ALTER TABLE name_of_the_table CHECK CONSTRAINT name_of_the_constraint;

Любые предыдущие нарушения не будут проверены или исправлены, но любые записи после применения ограничения будут проверены.

StanleyJohns
источник
-2

В ответе Нико есть 2 ошибки (2 условия object_id отсутствуют). И не надо group by:

SELECT  @sql = 'DROP INDEX ' + idx.name + ' ON ' + tbl.name
FROM    sys.indexes             idx 
INNER JOIN sys.tables           tbl     ON idx.object_id = tbl.object_id 
INNER JOIN sys.index_columns    idxCol  ON idx.index_id = idxCol.index_id   AND idx.object_id = idxCol.object_id 
INNER JOIN sys.columns          col     ON idxCol.column_id = col.column_id AND  idxCol.object_id = col.object_id
WHERE   idx.type <> 0 
AND     tbl.name = 'file_transfer_log' 
AND     col.name = 'tender_id';
Вал Старовойтов
источник
1
Посмотрите, почему я должен зарегистрировать свой аккаунт? в FAQ по обмену стека.
Пол Уайт 9