SQL Serverに現在無効になっている外部キー制約がある場合は、以下のコードを使用して再度有効にすることができます。
外部キー制約を有効にすると、テーブル内の既存のデータをチェックするかどうかを指定するオプションがあります。これは、CHECK
を有効にした場合にも当てはまります 制約。
以下は、これらのさまざまなオプションをそれぞれ指定しながら、外部キー制約を有効にするコード例です。
例1-WITHCHECKを使用して制約を有効にする
これが推奨される方法です(使用しない特別な理由がない限り)。
FK_Albums_Artists
と呼ばれる外部キー制約を有効にする例を次に示します。 :
ALTER TABLE Albums WITH CHECK CHECK CONSTRAINT FK_Albums_Artists;
ここでは、WITH CHECK
を明示的に述べています 、これは、制約を有効にする前に既存のデータをチェックするようにSQLServerに指示します。いずれかのデータが制約に違反している場合、制約は有効にならず、エラーが発生します。
これは、参照整合性を強制するため、優れています。
新しい外部キー制約を作成する場合、これがデフォルト設定です。ただし、既存の制約を有効にすると(ここで行っているように)、ではありません。 デフォルト設定。
例2–WITHNOCHECKを使用して制約を有効にする
この例では、既存のデータをチェックせずに制約を有効にします。
ALTER TABLE Albums WITH NOCHECK CHECK CONSTRAINT FK_Albums_Artists;
ここでは、WITH NOCHECK
を明示的に述べています 、SQLServerに既存のデータをチェックしないように指示します。これは、テーブルに制約に違反するデータがすでに含まれている場合でも、制約が有効になることを意味します。
これは、制約を有効にする場合のデフォルト設定です(ただし、制約を作成する場合はデフォルト設定ではありません)。
これを使用するいくつかの理由の1つ(おそらく唯一の理由)は、データベースに無効なデータを保持したい場合です。おそらく、1行以上の無効なデータを入力する必要があるが、将来のすべてのデータが制約に準拠する必要があるという1回限りの例外があります。
ただし、これを行うことに関連するリスクはまだあります。これについてMicrosoftが言わなければならないことは次のとおりです。
まれな場合を除いて、これを行うことはお勧めしません。新しい制約は、それ以降のすべてのデータ更新で評価されます。
WITH NOCHECK
によって抑制された制約違反 制約が追加されたときに、制約に従わないデータで行を更新すると、将来の更新が失敗する可能性があります。
したがって、WITH NOCHECK
を使用します 後で問題が発生する可能性があります。
例3–デフォルトオプションを使用して制約を有効にする
デフォルトのオプションを使用した例を次に示します。
ALTER TABLE Albums CHECK CONSTRAINT FK_Albums_Artists;
この例は、前の例と同等です。チェックするかどうかを指定しなかったため、SQLServerはWITH NOCHECK
が必要であると想定します。 。
したがって、必ずWITH CHECK
を明示的に指定してください 参照整合性の問題を回避したい場合。
WITHNOCHECKを使用すると信頼が失われます
(デフォルト)WITH NOCHECK
を使用して制約を有効にした場合 、注意する必要がある1つの結果は、SQLServerがその制約を信頼しなくなることです。信頼できないものとしてフラグを立てます。実際、制約を無効にすると、すでに信頼できないというフラグが立てられています。
SQLServerにはis_not_trusted
があります 1
に設定するフラグ 外部キー制約を無効にした場合(つまり、信頼されていない場合)、それを0
に設定する唯一の方法 (信頼できる)WITH CHECK
を指定することです 制約を再度有効にするとき。一方、WITH NOCHECK
を使用する 既存のデータをチェックせずに有効にするだけです。
WITH CHECK
を使用する 、有効にする前に、制約が既存のすべてのデータをチェックすることを確認します。有効にできる唯一の方法は、既存のすべてのデータが制約に準拠している場合です。既存のすべてのデータをチェックしたら、制約を信頼できます。
例4–信頼できる/無効になっているステータスを確認する
sys.foreign_keys
にクエリを実行すると、信頼済みおよび無効のステータスを確認できます。 システムビュー。
このように:
SELECT name AS 'Constraint', is_disabled, is_not_trusted FROM sys.foreign_keys;
結果:
+-------------------+---------------+------------------+ | Constraint | is_disabled | is_not_trusted | |-------------------+---------------+------------------| | FK_Albums_Artists | 0 | 1 | | FK_Albums_Genres | 0 | 0 | +-------------------+---------------+------------------+
これは、前の例( FK_Albums_Artists )で有効にした制約を示しています。 )は信頼されていません。
これは、デフォルト設定であるWITH NOCHECK
を使用して有効にしたためです。 。
WITH CHECK
を使用して再度有効にした場合 、次のようになります:
ALTER TABLE Albums WITH CHECK CHECK CONSTRAINT FK_Albums_Artists; SELECT name AS 'Constraint', is_disabled, is_not_trusted FROM sys.foreign_keys;
結果:
+-------------------+---------------+------------------+ | Constraint | is_disabled | is_not_trusted | |-------------------+---------------+------------------| | FK_Albums_Artists | 0 | 0 | | FK_Albums_Genres | 0 | 0 | +-------------------+---------------+------------------+
幸い、この場合、制約に違反するデータはなかったため、制約は正常に有効化され、信頼が回復しました。
制約に違反するデータがあった場合、エラーが表示され、制約の信頼を回復する前にデータを修正する必要がありました。