2016-04-29 15 views
3

私はこの課題を解決したいと思います(解決できるはずです)。 次の表があります。テーブルには座席予約が含まれています。開始日と終了日の間のすべての座席は予約されています。サブクエリを使用したOracleのチェック制約[エクササイズ]

CREATE TABLE reservation ( 
    owner CHAR(10) NOT NULL PRIMARY KEY, 
    start INTEGER NOT NULL, 
    end INTEGER NOT NULL 
) 

ない場所が二度予約しないことを、制約何をチェックして、このテーブル定義を拡張します。

私が知る限り、チェック制約内でサブクエリを使用することはできません。だから私はどんな種類の制約を使うことができますか?

+1

を私の知る限り、あなたは、制約を使用してこれを行うことはできません。 trigger.stackoverflow.com/questions/8770552/can-i-have-a-constraint-on-count-of-distinct-values-in-a-column-in-sql –

+0

はいこれまでに知っていることはthatsですしかし、これが可能かどうか疑問に思います。 –

+0

テーブルを変更できますか(列を追加するなど)?はいの場合は、可能です。複雑ではあるが、DRI単独(外部キー、ユニークおよびCHECK制約)によって可能。 –

答えて

3

これは単一のCHECKという制約では実行できません。基本的には、テーブルの複数の行に依存する制約なのでです。

ある意味ではUNIQUEという制約に似ています。一意の制約では、2つの行が同じ値を持つことはできません。この場合、2つの行が重複する範囲を持つことはできません。したがって、等価条件(=)を範囲の重複をチェックする条件に置き換えることができれば、それは正しいでしょう。

別のDBMS(Postgres)では、独自のEXCLUDEという制約を使用して、これと同様の制約を厳密に適用することは実際可能です。オラクルで


今と共通FOREIGN KEYUNIQUECHECK制約を持っている他のDBMSあなたが別の列を追加することにより、テーブルデザインを変更することが許可されている場合、それは、実際には可能ですが、複雑です:

CREATE TABLE reservation ( 
    owner CHAR(10) NOT NULL PRIMARY KEY, 
    start INTEGER NOT NULL, 
    end INTEGER NOT NULL, 
    previous_end INTEGER NULL, 

    CONSTRAINT valid_range 
     CHECK (start <= end), 
    CONSTRAINT unique_end 
     UNIQUE (end), 
    CONSTRAINT previous_range_fk 
     FOREIGN KEY (previous_end) 
     REFERENCES reservation (end), 
    CONSTRAINT valid_previous 
     CHECK (previous_end < start) 
) ; 

といいです。基本的にテーブルをリンクリストにするだけで、previous_endの値を正しく指定するだけです。範囲が重ならないように、すべての制約が一緒に機能します。

+0

実際、私はそれにも 'UNIQUE(previous_end)'制約が必要だと思います。私は、leditと正しい。 –

0

あなたはマテリアライズド・ビューを使用してこの問題を解決することができます

CREATE TABLE reservation ( 
    owner CHAR(10) NOT NULL PRIMARY KEY, 
    "start" INTEGER NOT NULL, 
    "end" INTEGER NOT NULL 
); 

CREATE MATERIALIZED VIEW LOG ON reservation 
    WITH SEQUENCE, ROWID("start","end") 
    INCLUDING NEW VALUES; 

CREATE MATERIALIZED VIEW reservation_MV 
    BUILD IMMEDIATE 
    REFRESH FAST ON COMMIT 
    AS SELECT "start" + LEVEL - 1 AS table_number 
     FROM reservation 
     CONNECT BY "start" + LEVEL - 1 <= "end"; 

ALTER TABLE reservation_MV ADD CONSTRAINT reservation__mv__pk 
    PRIMARY KEY (table_number);