web-dev-qa-db-ja.com

SQL Serverの列のNULL可能性の変更

次の表があるとします。

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は機能し、field1nullを許可します。

それでも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を使用しています。

ありがとうございました。

5
a1ex07

関連ドキュメント ここにあります

ALTER COLUMN名前付きの列を変更または変更することを指定します。

変更された列を次のいずれかにすることはできません。

  • インデックスで使用され、列がvarcharnvarchar、またはvarbinaryデータ型でない限り、データ型は変更されず、新しいサイズは古いサイズであり、インデックスはPRIMARY KEY制約の結果ではありません。

  • 列がvarcharnvarchar、または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
4
Martin Smith

Field1およびfield2のインデックスにより、列をNULLからNOT NULLに変更できません。インデックスを削除し、NOT NULLに変更してから、インデックスを再作成します。

0
Eli

NULLNOT NULLよりも緩い制限です。

NOT NULLに変更しようとするとNULLフィールドがあった場合(制約違反で失敗)、_NOT NULLがある場合にNULLに変更するとどうなりますか(影響なし)。

制約を作成するとき、テーブルの変更(または失敗)の前に、その制約に準拠するようにデータを検証する必要があります-私が観察したところによると、この動作は変更またはドロップでは発生せず、代わりにこの方法で制約を変更します単に防止されます。

0
iivel