Löschen einer Einschränkung (Index) für eine Spalte

12

Wie kann ich den Typ für eine Tabelle ändern, für die ein Index vorhanden ist? Ich habe versucht, eine Änderungsspalte in einer leeren Tabelle zu erstellen, um den Typ von Datum und Uhrzeit auf varchar (15) zu ändern. Dabei wurde die Fehlermeldung ausgegeben, dass er Abhängigkeiten von der Spalte hatte (was sich als Indizes herausstellte).

Ich konnte dies lokal umgehen, indem ich mit der rechten Maustaste auf den Index klickte und ein Skript für einen Drop erstellte, aber ich muss dies auf anderen Servern bereitstellen, auf denen ich keinen Zugriff auf den Indexnamen habe.

Gibt es eine Möglichkeit, ein Skript zu erstellen, mit dem jeder Index gelöscht werden kann? Lassen Sie mich diesen Datentyp in der Spalte ändern und dann den Index lesen? Vielen Dank!

user1480
quelle

Antworten:

7

Sie können die Ansicht sys.indexes verwenden, um Indizes abzurufen. Sie können diese Tabelle mit sys.tables, sys.columns und sys.index_column verknüpfen, um Informationen zum Erstellen eines dynamischen Ablageindex abzurufen. Mit dieser einfachen Auswahl können Sie Ihren Drop-Index erstellen. Mit der where-Klausel können Sie die Tabellen und Spalten filtern. Wenn Sie Table1.Column1 ändern möchten, müssen Sie diesen Namen verwenden, um die Auswahl zu filtern und die richtige delete-Anweisung zu erhalten

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

Hoffe das wird dir helfen

Nico
quelle
3
Beim Beitritt müssen Join-Anweisungen mit idx.object_id = idxCol.object_id & idxCol.object_id = col.object_id angereichert werden. Eine Gruppierung ist nicht erforderlich.
Bax
2

Um eine Spalte zu ändern, müssen Sie zuerst den Index oder andere Einschränkungen, die diese Spalte enthalten, löschen und anschließend den Index / die Einschränkung erneut erstellen. Diese Aufgabe muss jedoch von einem Datenbankadministrator ausgeführt werden, da sich das Löschen eines Index oder einer Einschränkung einerseits auf die abgefragten Daten auswirkt, während der Index gelöscht wird, und andererseits die gesamte Tabelle für die Zeit blockiert, in der der Index wiederhergestellt wird. erstellt. Sie müssen sicherstellen, dass die Benutzer über diese kleine oder große (abhängig von der Tabellengröße) Wartung informiert sind. Viel Glück!

Die Indexerstellung kann jedoch mit der Option Online erfolgen, die weniger blockierend ist.

yrushka
quelle
0

Wenn Sie den Index zuerst löschen, können Sie ihn nicht erneut lesen, es sei denn, der Index wird neu erstellt. Was Sie tun können, um die Durchsetzung der Einschränkung zu deaktivieren.

ALTER TABLE name_of_the_table NOCHECK CONSTRAINT name_of_the_constraint;

Nachdem dieses Skript ausgeführt wurde, wird die Einschränkung nicht erzwungen, und Sie können Daten eingeben, ohne sich um die Einschränkungsprüfungen kümmern zu müssen. Sie können die Tabelle erneut ändern, um die Einschränkungen wieder zu aktivieren.

ALTER TABLE name_of_the_table CHECK CONSTRAINT name_of_the_constraint;

Alle vorherigen Verstöße werden nicht überprüft oder korrigiert, aber alle Einträge, nachdem die Einschränkung erzwungen wurde, werden überprüft.

StanleyJohns
quelle
-2

Es gibt 2 Fehler in Nikos Antwort (2 object_id Bedingungen fehlen). Und keine Notwendigkeit 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
quelle
1
Bitte sehen Sie unter Warum sollte ich mein Konto registrieren? in den Stack Exchange FAQ.
Paul White 9