2011-01-10 16 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'のレコードを最大1つ持つことを意味しますか? –

+0

はい、正しいです。 – JamesC

答えて

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

+1

+1は制約違反を示します。 –

6

この場合の最も簡単な方法は、関数ベースのインデックスを作成することが一般的です。 Zが「N」がない場合

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

ようなものは、両方のCASE文がNULLに評価し、Oracleは(インデックス小さくする)インデックス構造にX & Y値を格納する必要はありません。 zが 'N'の場合、x &のy値は両方ともインデックスに格納され、インデックスは他の複合インデックスと同様に動作します。

0

を私はそのsitautionで行うことは、カラムなどを作成することです持っているあなたの場合、中Z

  • 特定の値(例えば、あなたの「N」)私は一意であるためにそれを必要とする場合には
  • そうでない場合はnull、意味不明:2つの未知の値がないと考えられています互いに等しい。

次に、固有の制約UNIQUE(X,Y,Z)を作成できます。

XとY、Z = "N"の2つの行を追加すると、エラーが発生します。 XとYが等しい2つの行をZ = nullの両方で追加します。

+0

列Zには、制約を渡す必要がある別の値を保持できます。 SQLで更新された質問。 – JamesC

関連する問題