int
PK列(これは)の容量が不足したので、IDENTITY
これを実行したいと思いますbigint
が、単純なALTER TABLE
テーブルではその大きなテーブルを処理できないようです。だから私の質問は、実際の値を維持したままPK列のタイプを変更するにはどうすればよいですか?また、参照テーブルも変更する必要がありますか?
4 に答える
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 編集済み (Alexey に感謝)
これはクリーンで、バッチで実行可能で、よく理解されています。
子テーブルも変更する必要があります。結局のところ、それらにも大きな int を挿入しようとしています。最初に子テーブルを切り替えます
これは簡単でも短いプロセスでもありません。設定された日付にデータベースがメンテナンスのためにダウンすることをユーザーに伝え(開発にかかる時間によってどれくらいの時間を測定できるかを判断できます)、作成中にデータベースをシングルユーザーモードにリセットすることをお勧めしますこれらの変更。別のテーブルに切り替えるときに、ユーザーが 1 つのテーブルに追加 (または変更) したデータを失いたくありません。なんらかの理由でメンテナンス ウィンドウを使用できない場合 (データの整合性を維持するために、そうするよう強くお勧めします)、最初に子テーブルを変更して、挿入エラーを回避する必要があります。すぐに大きな数字が表示されます。
すべてを再作成する必要があるため、デフォルト、トリガー、チェック定数インデックスなどを含むデータベース構造全体を必ずスクリプト化してください。
これはすべて、dev のスクリプトを使用して行うようにしてください。これにより、プロセスをテストしたら、1 つの prod を実行するのがはるかに簡単になります。
変更された PK データ型で新しいデータベースを作成し、データをエクスポート/インポートするか、新しいデータベースに一括挿入してから、新しいデータベースの名前を変更することしかできないと思います。もちろん、多くの参照テーブルがあり、新しい PK データ型が以前のものと互換性がない場合、これは実際の値です。