2012-09-15 99 views
4

我有一個表叫Room,它有列(ID,型號,價格...等)檢查約束列之間值檢查

我要添加約束雙方typeprice這樣的:

  • 如果單個(或多個),那麼價格不應該大於50,
  • 如果雙(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 
+0

nop ....所有價格都低於他們的要求值 – user1672735

+0

@ user1672735 - 你怎麼知道的?該錯誤清楚地表明'*原因:一個alter table操作試圖驗證一個檢查約束,以填充表中有不合適的值。 – Annjawn

回答

10

這聽起來像你需要OR在一起的三個條件,不AND在一起。這是不可能的任何行,以滿足所有三個criteria-- 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))); 
+2

@ user1672735可能還希望/需要添加條件(在此檢查約束中或在單獨的非空約束中)來處理或防止「TYPE」和/或「PRICE」爲空的情況。例如,如果「TYPE」或「PRICE」爲空(這可能不是預期的),那麼發佈的修改約束本身不會阻止插入行。 –

+0

是加入或做的工作....謝謝! – user1672735

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 
    ); 
1

您收到錯誤消息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:關於此主題的更多背景信息請參見this blogpost of mine