4

という名前のテーブルがRoomあり、列 (ID、タイプ、価格など) があります。

type両方に制約を追加したいのですが、次のpriceようにします。

  • シングルの場合、価格は 50 を超えてはなりません。
  • double (d) の場合、価格は 100 を超えてはならず、
  • ファミリー (f) の場合、価格は 150 を超えてはなりません

このように追加しようとしましたが、エラーが発生します。これをどのように書くべきかわかりません:

ALTER TABLE ROOM 
ADD (CONSTRAINT CHK_PRICE CHECK (
(TYPE='S' AND PRICE <= 50) AND 
(TYPE='D' AND PRICE <=100) AND 
(TYPE='F' AND PRICE <= 150)));

受け取ったエラーは次のとおりです。

SQL Error: ORA-02293: cannot validate (xxxx.CHK_PRICE) - check
constraint violated
02293. 00000 - "cannot validate (%s.%s) - check constraint violated"
*Cause:    an alter table operation tried to validate a check constraint to
           populated table that had nocomplying values.
*Action:   Obvious
4

3 に答える 3

11

OR一緒にではなく、3つの条件を一緒にする必要があるようですAND。どの行も3つの基準すべてを満たすことは不可能ですtype。つまり、S、D、およびFの値を同時に持つことはできません。

ALTER TABLE ROOM 
  ADD (CONSTRAINT CHK_PRICE CHECK (
        (TYPE='S' AND PRICE <=  50) OR -- <-- OR, not AND
        (TYPE='D' AND PRICE <= 100) OR -- <-- OR, not AND
        (TYPE='F' AND PRICE <= 150)));
于 2012-09-15T03:13:01.970 に答える
2

新しく作成したチェック制約を満たさないデータがテーブルに既にあるため、エラー メッセージ ORA-02293 が表示されます。

ここで重要なことは、ここで検証するビジネス ルールは 1 つではなく、3 つあるということを理解することです。そして、制約を検証するユーザーにとって、挿入している行の何が問題なのかを正確に知ることが最も便利です。そういうわけで、私はこれらの制約に行きます:

SQL> create table room (id,type,price)
  2  as
  3  select 1, 'S', 50 from dual union all
  4  select 2, 'D', 80 from dual union all
  5  select 3, 'F', 110 from dual
  6  /

Table created.

SQL> alter table room add constraint single_room_below_50 check (type != 'S' or price <= 50)
  2  /

Table altered.

SQL> alter table room add constraint double_room_below_100 check (type != 'D' or price <= 100)
  2  /

Table altered.

SQL> alter table room add constraint family_room_below_150 check (type != 'F' or price <= 150)
  2  /

Table altered.

SQL> insert into room values (4, 'S', 60)
  2  /
insert into room values (4, 'S', 60)
*
ERROR at line 1:
ORA-02290: check constraint (RWIJK.SINGLE_ROOM_BELOW_50) violated

よろしく、
ロブ。

PS: この件に関する詳細な背景については、このブログ投稿を参照してください。

于 2012-09-15T14:55:08.330 に答える
2

そうですね、3 つのチェック条件で「and」の代わりに「or」を使用する必要があります。

また、エラー メッセージ (ORA-02293: 検証できません) は、テーブル ルームに整合性制約に違反するデータ行があることを通知します。さらに、オプション VALIDATE または NOVALIDATE を使用して、テーブル内の既存のデータが制約に準拠する必要があるかどうかを指定できます。ルーム内のこれらの既存のデータ行を検証したくない場合は、この制約を NOVALIDATE で指定できます。VALIDATE がデフォルトです。

    ALTER TABLE ROOM    
    ADD (CONSTRAINT CHK_PRICE CHECK 
    (
    (TYPE='S' AND PRICE <=  50) OR -- <-- OR, not AND
    (TYPE='D' AND PRICE <= 100) OR -- <-- OR, not AND
    (TYPE='F' AND PRICE <= 150)
    )
    NOVALIDATE   -- VALIDATE is default
    );
于 2012-09-15T04:03:45.233 に答える