4

我有一个名为的表Room,它有列(ID、类型、价格......等)

我想为两者添加约束typeprice例如:

  • 如果是单件,则价格不应大于 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将三个条件放在一起,而不是AND它们放在一起。任何行都不可能满足所有三个条件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:无法验证)通知您的表室中有一些数据行违反了您的完整性约束。此外,您可以使用选项 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 回答
2

您收到错误消息 ORA-02293,因为您的表中已经有不满足新创建的检查约束的数据。

我认为这里的一个重要部分是要意识到您在这里没有要验证的一个业务规则,而是三个。对于验证约束的用户来说,最方便的是确切地知道他插入的行有什么问题。所以这就是为什么我会去这些限制:

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 回答