Descartar una restricción (índice) en una columna

12

¿Cómo puedo modificar el tipo en una tabla que tiene un índice? Intenté hacer una columna alter en una tabla vacía para modificar el tipo de fecha y hora a varchar (15) y obtuve errores que decían que tenía dependencias en la columna (que resultaron ser índices).

Pude evitarlo fácilmente localmente haciendo clic derecho en el índice y creando una secuencia de comandos, pero necesito implementar esto en otros servidores donde no tendré acceso al nombre del índice.

¿Hay alguna manera de hacer un script que elimine cualquier índice, déjame hacer ese cambio de tipo de datos en la columna y luego leer el índice? ¡Gracias!

usuario1480
fuente

Respuestas:

7

Puede usar la vista sys.indexes para obtener índices. Puede unir esta tabla a sys.tables, sys.columns y sys.index_column para obtener información para crear un índice de caída dinámico. Puede usar esta simple selección para generar su índice de caída. Puede usar la cláusula where para filtrar las tablas y las columnas. Si desea cambiar Table1.Column1, debe usar esos nombres para filtrar la selección y obtener la instrucción de eliminación correcta

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 esto te ayudará

Nico
fuente
3
al unirse, debe enriquecer las declaraciones de unión con idx.object_id = idxCol.object_id & idxCol.object_id = col.object_id y no es necesario agruparlas.
Bax
2

Para alterar cualquier columna, primero debe eliminar el índice o cualquier otra restricción que contenga esa columna, y luego crear el índice / restricción nuevamente. Pero esta tarea debe ser realizada por un DBA porque cualquier caída en el índice o restricción afectará por un lado los datos que se consultan, mientras que el índice se cae y, por otro lado, se bloquea en toda la tabla durante el tiempo que el índice se restablece creado. Debe asegurarse de que los usuarios estén al tanto de este mantenimiento pequeño o grande (depende del tamaño de la tabla). ¡Buena suerte!

Sin embargo, la creación del índice se puede hacer con la opción en línea que es menos bloqueante.

yrushka
fuente
0

Si suelta el índice primero, no podrá volver a leerlo, a menos que se vuelva a crear el índice. Lo que puede hacer para deshabilitar la aplicación de la restricción.

ALTER TABLE name_of_the_table NOCHECK CONSTRAINT name_of_the_constraint;

Después de ejecutar este script, la restricción no se aplicará y puede ingresar datos sin preocuparse por las comprobaciones de restricciones. Puede modificar la tabla nuevamente para volver a habilitar las restricciones.

ALTER TABLE name_of_the_table CHECK CONSTRAINT name_of_the_constraint;

No se verificará ni corregirá ninguna violación previa, pero se verificará cualquier entrada después de que se haya aplicado la restricción.

StanleyJohns
fuente
-2

Hay 2 errores en la respuesta de Niko (faltan 2 condiciones object_id). Y no es necesario 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
fuente
1
Por favor, consulte ¿ Por qué debo registrar mi cuenta? en las preguntas frecuentes de Stack Exchange.
Paul White 9