生成されるスクリプトではNOCHECKが使用されるため、テーブルの値が準拠していない場合でも、制約は常に作成されます。これは、自動的に生成されたスクリプトの方がデータベーススキーマが正しく作成または修正されるためです。
最初に、生成されたスクリプトの2番目のステートメントは、クエリオプティマイザが制約を考慮することを保証することだと思いました。しかし、さらに調査すると、2番目の声明は効果がないと思われます。私の2番目の答えを見てください。
WITH CHECKを使用して手動で実行しているときは、ステートメントが失敗したことを直ちに確認し、是正処置を取ることができます。次に、ステートメントを再度実行します。
WITH NOCHECKオプションを使用すると、データが無効であることに気付かないことがあります。個人的には、制約を追加するためにALTER TABLEを実行するときは、常にWITH CHECKを使用します。また、Books Onlineでは、WITH NOCHECKを使用することはお勧めできないことを示しています。
まず、テーブルを作成していくつかの値を挿入しましょう。
CREATE TABLE dbo.T
(
id int NOT NULL IDENTITY(1,1),
[column] nchar(1) NOT NULL
);
INSERT INTO dbo.T ([column])
VALUES (N'A'), (N'B'), (N'C'), (N'E');
WITH CHECKを指定してテーブルを変更し、制約を追加してください。これは、テーブル内の一部のデータが制約に準拠していないために失敗します。
ALTER TABLE dbo.T
WITH CHECK
ADD CONSTRAINT CK_Column CHECK ([column] IN (N'A', N'B', N'C', N'D'));
制約がsys.check_constraintsのシステム・カタログ・ビューを使用して、作成されている場合を見てみましょう。これは、制約が作成されていないことを示しています。
SELECT *
FROM sys.check_constraints
WHERE [parent_object_id] = OBJECT_ID(N'dbo.T');
、再びNOCHECK WITH指定し、この時間を試してみてください。今回は正常に完了します。ただし、テーブル内のデータが無効であるという警告はなく、望ましくない可能性があります。
ALTER TABLE dbo.T
WITH NOCHECK
ADD CONSTRAINT CK_Column CHECK ([column] IN (N'A', N'B', N'C', N'D'));
そして、我々はチェック制約が作成されていることを確認することができます。
参照オンラインブック> ALTER TABLE(Transact-SQLの):https://msdn.microsoft.com/en-GB/library/ms190273.aspx> CHECK WITH | WITH NOCHECK
既存のデータに対して新しいCHECKまたはFOREIGN KEY制約を検証しない場合は、WITH NOCHECKを使用します。これを行うことはお勧めできませんが、ごくまれにあります。新しい制約は、後のすべてのデータ更新で評価されます。制約が追加されたときにWITH NOCHECKによって抑制される制約違反は、制約に従わないデータで行を更新すると、将来の更新が失敗する可能性があります。
二自動的に生成されたステートメントの理由はここに明らかにされています
クエリオプティマイザは、NOCHECKで定義された制約を考慮していません。このような制約は、ALTER TABLE表WITH CHECK CHECK CONSTRAINT ALLを使用して再度有効にするまで無視されます。 ...私の前の回答の後に少し深く
を掘る