次の表があるとします。
CREATE TABLE test(test_id int not null identity primary key,
field1 int not null,
field2 int
);
CREATE INDEX IDX_test_field1 ON test(field1);
CREATE INDEX IDX_test_field2 ON test(field2);
今ALTER TABLE test ALTER COLUMN field1 int
は機能し、field1
はnull
を許可します。
それでもALTER TABLE test ALTER COLUMN field2 int not null
のため
1つ以上のオブジェクトがこの列にアクセスするため、ALTER TABLE ALTER COLUMN field2が失敗しました。
また、field1
戻る not null
。
ただし、チェック制約は何度でも追加および削除できます。
ALTER TABLE test ADD CONSTRAINT CHK_NN_field2 CHECK (field2 IS NOT NULL);
DROP CONSTRAINT CHK_NN_field2` without any problems.
明確に定義された動作ですか?誰かがそれが起こる理由を説明したり、ドキュメントを指摘したりできますか?
必要に応じて、SQL Server 2008 R2を使用しています。
ありがとうございました。
関連ドキュメント ここにあります
ALTER COLUMN
名前付きの列を変更または変更することを指定します。変更された列を次のいずれかにすることはできません。
インデックスで使用され、列が
varchar
、nvarchar
、またはvarbinary
データ型でない限り、データ型は変更されず、新しいサイズは古いサイズであり、インデックスはPRIMARY KEY
制約の結果ではありません。列が
varchar
、nvarchar
、またはvarbinary
データ型である場合を除き、CREATE STATISTICS
ステートメントによって生成される統計で使用され、データ型は変更されず、新しいサイズが古いサイズ以上であるか、列がnull以外からnullに変更された場合。まず、DROP STATISTICS
ステートメントを使用して統計を削除します。クエリオプティマイザーによって自動的に生成された統計は、ALTER COLUMN
によって自動的に削除されます。
実際には、SQL Serverでは、ドキュメントに記載されている以外にもいくつかのケースが許可されているようです。
質問で示したように、実際に機能するのはALTER TABLE test ALTER COLUMN field1 int null
です。そのため、インデックスで使用される列の変更に対する制限は、ユーザーが作成した統計の制限と同じように見えます。
さらに、主キーについて述べられている警告も正しくないようです。以下は正常に動作します。
CREATE TABLE test2(pk varchar(10) primary key);
ALTER TABLE test2 ALTER COLUMN pk varchar(100) NOT NULL
Field1およびfield2のインデックスにより、列をNULLからNOT NULLに変更できません。インデックスを削除し、NOT NULLに変更してから、インデックスを再作成します。
NULL
はNOT NULL
よりも緩い制限です。
NOT NULL
に変更しようとするとNULL
フィールドがあった場合(制約違反で失敗)、_NOT NULL
がある場合にNULL
に変更するとどうなりますか(影響なし)。
制約を作成するとき、テーブルの変更(または失敗)の前に、その制約に準拠するようにデータを検証する必要があります-私が観察したところによると、この動作は変更またはドロップでは発生せず、代わりにこの方法で制約を変更します単に防止されます。