巨大なテーブルPK列のデータ型を変更する
-
07-07-2019 - |
質問
PK列( IDENTITY
)の int
容量がなくなったため、これを bigint
、しかし単純な ALTER TABLE
はそのような大きなテーブルを処理できないようです。したがって、私の質問は次のとおりです。実際の値を保持したままPK列のタイプを変更するにはどうすればよいですか。参照テーブルも変更する必要がありますか。
解決
KLEの提案に加えて、次のクエリが役立つ場合があります。
oldTableを参照するテーブルのすべての制約を無効にするには、次のクエリの出力を実行してください。
SELECT 'ALTER TABLE ' + OBJECT_NAME(fk.parent_object_id) + ' NOCHECK CONSTRAINT ' + fk.name
FROM sys.foreign_keys fk
INNER JOIN sys.foreign_key_columns AS fkc ON fk.OBJECT_ID = fkc.constraint_object_id
WHERE OBJECT_NAME (fk.referenced_object_id) = 'oldTable'
すべてのデータを新しいテーブルに移動するには、フィールドを変更してこれを試してください:
INSERT INTO newTable
SELECT CONVERT(BIGINT, ID) AS ID, COL1, COL2, ..., COLN
FROM oldTable
古いテーブルを削除するには:
DROP TABLE oldTable
新しいテーブルの名前を古い名前に変更するには:
sp_rename newTable, oldTable
oldTableを参照するテーブルのすべての制約を再度有効にするには、次のクエリの出力を実行してください。
SELECT 'ALTER TABLE ' + OBJECT_NAME(fk.parent_object_id) + ' CHECK CONSTRAINT ' + fk.name
FROM sys.foreign_keys fk
INNER JOIN sys.foreign_key_columns AS fkc ON fk.OBJECT_ID = fkc.constraint_object_id
WHERE OBJECT_NAME (fk.referenced_object_id) = 'oldTable'
ご希望の場合...
他のヒント
私たちがやることは:
テーブルを保存
- 正しい構造で新しいテーブルを作成
- これらのテーブルのすべての制約、およびそれらを参照する制約を無効にします
- フィールドを変更して、すべてのデータを新しいテーブルに移動します。バッチで行うことができます
- 空の古いテーブルを削除する
- 新しいテーブルの名前を古い名前に変更します
-
すべてのテーブルのすべての制約を有効にします(一部のFK列と制約もおそらく修正が必要です...しかし、PKではないため、変更可能です)
6編集(アレクセイのおかげ)
これはクリーンで、バッチで実行可能で、よく理解されています。
子テーブルも変更する必要があります。結局、あなたは今、同様にそれらに大きなintを挿入しようとしているでしょう。最初に子テーブルを変更します
これは簡単なプロセスでも短いプロセスでもありません。データベースをメンテナンスのためにダウンさせることをユーザーに伝えることをお勧めします(開発にかかる時間でどれくらいの期間を測定できますか)、設定した日付にデータベースをシングルユーザーモードにリセットしますこれらの変更。他のテーブルに切り替えている間に、ユーザーが1つのテーブルに追加(または変更)したデータを失いたくありません。何らかの理由でメンテナンスウィンドウを使用できない場合(およびデータの整合性のために強くお勧めします)、最初に子テーブルを変更して、制限に本当に近い場合に挿入エラーを回避する必要がありますすぐに大きな数字が表示されます。
すべてを再作成するため、デフォルト、トリガー、チェックインデックスなどを含むdatbase構造全体のスクリプトを作成してください。
devのスクリプトを使用して、これらすべてを実行してください。プロセスをテストしたら、1つのprodを簡単に実行できます。
PKデータ型が変更された新しいデータベースのみを作成し、データをエクスポート/インポートするか、新規に一括挿入してから、新しいデータベースの名前を変更できると思います。もちろん、これは多くの参照テーブルがあり、新しいPKデータ型が以前のものと互換性がない場合に実際のものです。