sql >> データベース >  >> RDS >> Sqlserver

SQL Serverで外部キー制約を有効にする方法(T-SQLの例)

    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                |
    +-------------------+---------------+------------------+
    

    幸い、この場合、制約に違反するデータはなかったため、制約は正常に有効化され、信頼が回復しました。

    制約に違反するデータがあった場合、エラーが表示され、制約の信頼を回復する前にデータを修正する必要がありました。


    1. SQLServerでのテーブル変数のパフォーマンス

    2. MySQLクエリのシングルクォート、ダブルクォート、およびバックティック

    3. MySQLでのLEFT()関数のしくみ

    4. Oracle 12cでPBKDF2を使用するにはどうすればよいですか?