Удаление ограничения (индекса) в столбце
Как изменить тип таблицы, на которой есть индекс? Я попытался сделать столбец alter в пустой таблице, чтобы изменить тип от даты до varchar (15) и получил ошибки, заявив, что он имеет зависимости от столбца (который оказался индексом).
Мне удалось легко обойти это локально, щелкнув правой кнопкой мыши индекс и обработав патч, но мне нужно перевернуть это на других серверах, где у меня не будет доступа к имени индекса.
Есть ли способ сделать скрипт, который поместит любой индекс, позвольте мне изменить этот тип данных в столбце, а затем прочитать индекс? Спасибо!
4 ответа
Вы можете использовать представление sys.indexes для получения индексов. Вы можете присоединиться к этой таблице в sys.tables, sys.columns и sys.index_column, чтобы получить информацию о создании динамического индекса падения. Вы можете использовать этот простой выбор для генерации индекса drop. Вы можете использовать предложение where для фильтрации таблиц и столбцов. Если вы хотите изменить Table1.Column1, вы должны использовать это имя для фильтрации выбора, чтобы получить правильную инструкцию delete
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
Надеюсь, это поможет вам
Чтобы изменить любой столбец, сначала нужно отбросить индекс или любые другие ограничения, содержащие этот столбец, и после создания индекса /ограничения снова. Но эта задача должна выполняться администратором баз данных, потому что любое падение индекса или ограничения будет влиять, с одной стороны, на запрашиваемые данные - в то время как индекс отбрасывается, а с другой стороны кладет блокировку на всю таблицу на время, создано. Вы должны убедиться, что пользователи будут знать об этом небольшом или большом (в зависимости от размера стола) обслуживании. Удачи!
Однако создание индекса может быть сделано с помощью опции Online, которая меньше блокирует.
Если вы сначала снимете индекс, вы не сможете его прочитать, если только индекс не будет воссоздан. Что вы можете сделать для отключения принудительного ограничения.
ALTER TABLE name_of_the_table NOCHECK CONSTRAINT name_of_the_constraint;
После запуска этого сценария ограничение не будет применяться, и вы можете ввести данные, не беспокоясь о проверках ограничений. Вы снова можете изменить таблицу, чтобы снова включить ограничения.
ALTER TABLE name_of_the_table CHECK CONSTRAINT name_of_the_constraint;
Любые предыдущие нарушения не будут проверяться или исправляться, но будут отмечены любые записи после принудительного ограничения.
В ответе Нико есть 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';