Eliminando uma restrição (índice) em uma coluna

12

Como posso modificar o tipo em uma tabela que possui um índice? Tentei fazer uma alteração de coluna em uma tabela vazia para modificar o tipo de data e hora para varchar (15) e obtive erros dizendo que tinha dependências na coluna (que acabou sendo índices).

Consegui contornar esse problema facilmente localmente, clicando com o botão direito do mouse no índice e criando um script, mas preciso implementá-lo em outros servidores nos quais não terei acesso ao nome do índice.

Existe uma maneira de criar um script que elimine qualquer índice, deixe-me fazer esse tipo de dados mudar na coluna e depois ler o índice? Obrigado!

user1480
fonte

Respostas:

7

Você pode usar a exibição sys.indexes para obter índices. Você pode associar esta tabela a sys.tables, sys.columns e sys.index_column para obter informações e criar um índice dinâmico de descarte. Você pode usar essa seleção simples para gerar seu índice de drop. Você pode usar a cláusula where para filtrar as tabelas e as colunas. Se você deseja alterar Table1.Column1, use esses nomes para filtrar a seleção e obter a instrução de exclusão correta

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

Espero que isso ajude você

Nico
fonte
3
ao ingressar, você deve enriquecer as instruções de junção com idx.object_id = idxCol.object_id & idxCol.object_id = col.object_id e não há necessidade de agrupar.
Bax
2

Para alterar qualquer coluna, primeiro você deve eliminar o índice ou quaisquer outras restrições que contenham essa coluna e depois criar o índice / restrição novamente. Mas essa tarefa deve ser executada por um DBA, pois qualquer queda no índice ou restrição afetará, por um lado, os dados que estão sendo consultados - enquanto o índice é descartado e, por outro lado, bloqueia a tabela inteira pelo tempo em que o índice for recuperado. criada. Você precisa garantir que os usuários estejam cientes dessa manutenção pequena ou grande (depende do tamanho da tabela). Boa sorte!

No entanto, a criação do índice pode ser feita com a opção Online, que é menos bloqueadora.

yrushka
fonte
0

Se você soltar o índice primeiro, não poderá lê-lo novamente, a menos que o índice seja recriado. O que você pode fazer para desativar a imposição da restrição.

ALTER TABLE name_of_the_table NOCHECK CONSTRAINT name_of_the_constraint;

Após a execução desse script, a restrição não será aplicada e você poderá inserir dados sem se preocupar com as verificações de restrição. Você pode alterar a tabela novamente, para reativar as restrições.

ALTER TABLE name_of_the_table CHECK CONSTRAINT name_of_the_constraint;

Quaisquer violações anteriores não serão verificadas ou corrigidas, mas as entradas após a restrição ter sido imposta serão verificadas.

StanleyJohns
fonte
-2

Existem 2 erros na resposta do Niko (faltam 2 condições de object_id). E não é necessário 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';
Val Starovoitov
fonte
1
Consulte Por que devo registrar minha conta? nas Perguntas frequentes sobre troca de pilhas.
Paul White 9