2

私の質問は、制約のチェックに関するものです。通常の構文は次のとおりです。

ALTER TABLE barracks
ADD CONSTRAINT chk_barracks CHECK( status IN('Destroyed', 'constructed'))  

これは、列のステータスを破棄または構築する必要があることを意味します。

以下では、兵舎が null 値を受け入れないことを指定しています

 ALTER TABLE barracks
 ADD CONSTRAINT chk_barracks CHECK(status IN('Destroyed', 'constructed')
    AND status IS NOT NULL) 

今、列を追加しましcolourた。が構築されているかどうか を指定したい場合は、REDのみで、列STATUSNOT NULLにする必要がありますbarrackscolour

兵舎が破壊された場合

次にBLACKで、列STATUSNULLcolourである必要があります。

だからここに私が書いたチェック制約があります:

 ALTER TABLE barracks
 ADD CONSTRAINT chk_barracks CHECK( ((status IN ('Destroyed', 'constructed')
         AND status IS NOT NULL) 
         AND (color IN('RED') )) 
    OR (( status IN('Destroyed', 'constructed') 
         AND status IS NULL) 
         AND (color IN('BLACK') )))  

色が赤の場合でもNULL、列に挿入できるという問題status。上記の条件をチェックする方法でこの制約を解決するにはどうすればよいですか?

4

1 に答える 1

3

「Destroyed」、「Constructed」などの値を強制するために CHECK 制約を使用するのは悪い考えです。代わりにルックアップ テーブルへの外部キーを使用してください。他のことは別として、それは次のような論理的な不条理を防ぐでしょう:

( status IN('Destroyed', 'constructed') 
         AND status IS NULL) 

次に、より単純なチェック条件もあります。

( ( status is not null and color = 'RED') 
   or ( status is null and color = 'BLACK') 

少なくとも、2 つの別個のチェック制約が必要です。1 つは STATUS の値を検証するためのもので、もう 1 つは COLOR と STATUS が設定されているかどうかとの関係を検証するためのものです。


外部キーの詳細。次のようなテーブルを作成します。

 create table barracks_statuses
     ( status varchar2 (15) not null
       , constraint bsts_pk primary key (status)
 organization index;

 insert into barracks_statuses values ( 'Destroyed');
 insert into barracks_statuses values ( 'constructed');

次に、次のように外部キーを強制します。

alter table barracks
    add constraint barr_bsts_fk foreign key (status)
        references (status);

このようなアプローチは、柔軟性が向上するため便利です。「計画済み」などの新しいステータスを追加するか、複雑なチェック制約を書き直す代わりに、DML だけで「構築済み」のタイプミスを修正します。

于 2013-06-21T15:32:00.480 に答える