列の制約(インデックス)の削除


12

インデックスがあるテーブルのタイプを変更するにはどうすればよいですか?空のテーブルで列を変更して型を日付時刻からvarchar(15)に変更しようとしましたが、列(インデックスであることが判明)に依存しているというエラーが表示されました。

インデックスを右クリックしてドロップをスクリプト化することで、これをローカルで簡単に回避できましたが、インデックス名にアクセスできない他のサーバーでこれを展開する必要があります。

インデックスを削除するスクリプトを作成する方法はありますか?列でそのデータ型を変更してからインデックスを読み取ることができますか?ありがとう!

回答:


7

sys.indexesビューを使用してインデックスを取得できます。このテーブルをsys.tables、sys.columns、sys.index_columnに結合して、動的ドロップインデックスを作成するための情報を取得できます。この単純な選択を使用して、ドロップインデックスを生成できます。where句を使用して、テーブルと列をフィルタリングできます。Table1.Column1を変更する場合は、それらの名前を使用してselectをフィルタリングし、正しい削除ステートメントを取得する必要があります

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

列を変更するには、最初にその列を含むインデックスまたはその他の制約を削除し、インデックス/制約を再度作成する必要があります。ただし、インデックスまたは制約のドロップは、一方でクエリのデータに影響を与えるため、DBAがこのタスクを実行する必要があります-インデックスがドロップされている間、インデックスが再作成されている間はテーブル全体に閉塞が発生します作成した。ユーザーがこの小規模または大規模な(テーブルサイズに依存する)メンテナンスを認識するようにする必要があります。幸運を!

ただし、インデックスの作成は、ブロッキングの少ないオンラインオプションで実行できます。


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;

以前の違反はチェックまたは修正されませんが、制約が実施された後のエントリはチェックされます。


-2

Nikoの答えには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
アカウントを登録する理由をご覧くださいStack Exchange FAQにあります。
ポールホワイト9
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.