2011-01-10 65 views
8

Oracle是否支持表達式這樣的約束?帶表達式的Oracle唯一約束

通知Z = 'N'

ALTER TABLE A ADD CONSTRAINT U_A_KEY UNIQUE(X,Y,Z = 'N'); 

這是Unique constraint可能?

實施例:

INSERT INTO A VALUES('X','Y','N'); --OK 
INSERT INTO A VALUES('X','Y','Y'); --OK 
INSERT INTO A VALUES('X','Y','Y'); --OK 
INSERT INTO A VALUES('X','Y','N'); --VOLIATION 
+0

這是否意味着對於每個x,y組合,這意味着您最多隻需要一個Z ='N'的記錄? – 2011-01-10 15:30:36

+0

是的,這是正確的。 – JamesC 2011-01-10 15:33:19

回答

18

也許這給出了一個想法

drop table tq84_n; 

create table tq84_n (
    x number, 
    y number, 
    z varchar2(10) 
); 

create unique index tq84_n_x on tq84_n (
    case when z = 'N' then x || '-' || y 
     else null 
    end 
); 

後來:

insert into tq84_n values (4,5, 'N'); 

insert into tq84_n values (9,6, 'Y'); 
insert into tq84_n values (9,6, 'Y'); 

insert into tq84_n values (4,5, 'Y'); 

insert into tq84_n values (4,5, 'N'); 

最後一個動作:

ORA-00001: unique constraint (SPEZMDBA.TQ84_N_X) violated 
+0

滿足用例,感謝您的建議。 – JamesC 2011-01-10 16:00:09

6

在這種情況下最簡單的辦法通常爲創建一個函數的索引。像

CREATE UNIQUE INDEX u_a_key 
    ON a((CASE WHEN z = 'N' THEN x ELSE null END), 
      (CASE WHEN z = 'N' THEN y ELSE null END)); 

東西,如果z不「N」,既CASE語句計算爲NULL和Oracle不必在x & y值存儲在索引結構(使索引更小)。如果z是'N',則y值都存儲在索引中,並且索引與其他任何複合索引一樣。

0

我在sitaution做的是例如創建一個列Z你的情況,其中有:

  • 一個特定值(例如,您的「N」)的情況下,我需要它是唯一
  • 空,否則,意思是未知的:兩個未知值被認爲是不彼此相等。

然後,您可以創建您的唯一約束UNIQUE(X,Y,Z)

添加等於X和Y且Z =「N」的兩行,您將看到一個錯誤;用Z = null添加兩個等於X和Y的行,你不會。