フィールドを変更して、フィールドをチェックせずに null にならないようにすることができます。営業時間外に実行しないことが本当に心配な場合は、フィールドに制約を追加して、代わりに null でないことを確認できます。これにより、チェックなしオプションを使用して、400 万行のそれぞれをチェックして更新するかどうかを確認する必要がなくなります。
CREATE TABLE Test
(
T0 INT Not NULL,
T1 INT NUll
)
INSERT INTO Test VALUES(1, NULL) -- Works!
ALTER TABLE Test
WITH NOCHECK
ADD CONSTRAINT N_null_test CHECK (T1 IS NOT NULL)
ALTER COLUMN T1 int NOT NULL
INSERT INTO Test VALUES(1, NULL) -- Doesn't work now!
実際には 2 つのオプションがあります (3 つ目のオプションを追加、編集を参照):
- 新しい行が更新されないようにし、元の行を変更しないままにする制約を使用します。
- null の行を別のものに更新してから、not null 変更オプションを適用します。プロセスがテーブルからロックアウトされることを気にしない限り、これは実際には営業時間外に実行する必要があります。
特定のシナリオに応じて、いずれかのオプションが適している場合があります。ただし、営業時間外に実行する必要があるため、このオプションは選択しません。長い目で見れば、深夜に更新に費やす時間は、数時間節約するために近道をすることで直面する可能性のある頭痛と比較して、十分に費やされるでしょう.
以上のことから、オプション 2 を使用する場合は、勤務時間外の作業量を最小限に抑えることができます。列を変更する前に、行をnull以外に更新する必要があるため、カーソルをゆっくりと書き込むことができます(一度にすべてを行う場合と比較して)
- 各行を通過する
- null かどうかを確認する
- 適宜更新してください。これにはかなり時間がかかりますが、他のプログラムがテーブルにアクセスするのをブロックするテーブル全体をロックすることはありません。( with(rowlock)テーブルのヒントを忘れないでください!)
編集: 3 番目のオプションを考えました。適切な列を含む新しいテーブルを作成し、元のテーブルから新しいテーブルにデータをエクスポートできます。これが完了したら、元のテーブルを削除して、新しいテーブルの名前を古いものに変更できます。これを行うには、元の依存関係を無効にし、完了したら新しい依存関係を元に戻す必要がありますが、このプロセスにより、時間外に行う必要がある作業の量が大幅に削減されます。これは、管理スタジオを使用してテーブルの列の順序を変更するときに SQL Server が使用するのと同じアプローチです。このアプローチでは、チャンクで挿入を行い、システムに元に戻すストレスが発生しないようにし、他のユーザーがシステムにアクセスできないようにします。次に、営業時間外にオリジナルを削除し、2 番目の名前を変更し、
sp_renameの使用へのリンク。