質問

ここでちょっと実験を行った、Oracleデータベース(10g).ほか(Oracle)が実装できませんね一部の挿入を容認して、その他拒否されます。

create table sandbox(a number(10,0), b number(10,0));
create unique index sandbox_idx on sandbox(a,b);

insert into sandbox values (1,1); -- accepted
insert into sandbox values (1,2); -- accepted
insert into sandbox values (1,1); -- rejected

insert into sandbox values (1,null); -- accepted
insert into sandbox values (2,null); -- accepted
insert into sandbox values (1,null); -- rejected

insert into sandbox values (null,1); -- accepted
insert into sandbox values (null,2); -- accepted
insert into sandbox values (null,1); -- rejected

insert into sandbox values (null,null); -- accepted
insert into sandbox values (null,null); -- accepted

このことは、あってはならないことでる時には一行一列の値を未知のかを考えることができるとする持続可能な利用件の重複を防止:
1.したい着信拒否の重複が受け入れる場合に制約のあるカラムの値が不明である。
2.したい着信拒否複場合でも、時に制約のあるカラムの値が不明である。

うOracleを実装しも異なるもの:
3.拒否する重複が受け入れのみ) すべての 制約のあるカラムの値は不明である。

私はを考えることができる方法を用オラクルの実装を使用例(2)--例えば、特別な価値"不明"の列を非null.ができない図などの利用の場合(1).

その方法を教えてくださいOracle法はこのような態度を取るのか。

create table sandbox(a number(10,0), b number(10,0));
create unique index sandbox_idx on sandbox(a,b);

insert into sandbox values (1,1); -- accepted
insert into sandbox values (1,2); -- accepted
insert into sandbox values (1,1); -- rejected

insert into sandbox values (1,null); -- accepted
insert into sandbox values (2,null); -- accepted
insert into sandbox values (1,null); -- accepted

insert into sandbox values (null,1); -- accepted
insert into sandbox values (null,2); -- accepted
insert into sandbox values (null,1); -- accepted

insert into sandbox values (null,null); -- accepted
insert into sandbox values (null,null); -- accepted
役に立ちましたか?

解決 2

create unique index sandbox_idx on sandbox
 (case when a is null or b is null then null else a end,
  case when a is null or b is null then null else b end);

の機能指標!すべてNULLに変換されます - 基本的に私はちょうど私が(受け入れIE)を無視してもよろしいすべてのタプルを作るために必要。醜い、醜い突き合わせません。必要に応じて動作します。

別の質問に対する解決策の助けを借りてそれを考え出した:<のhref = "https://stackoverflow.com/questions/182262/how-to-constrain-a-database-table-so-only-oneこれだけ一つの行が列に特定の値を有することができるデータベーステーブルを制約する方法>行×-有することができる-特定の価値の「か

だから、そこに行くと、あまりにもトニー・アンドリュースにポイントを与えます。 :)

他のヒント

ファンクション索引を試してみてください

;(BがNULLである場合|| '' || B端ELSE THEN NULL CASE IS NULL THEN NULL)

サンドボックスに一意のインデックスを作成sandbox_idx

があり、この猫を肌する他の方法がありますが、これはその一つである。

んレーサビリティシステんが、ここのと考えていただきた場合、を含むことができ,列のインデックスにOracle.

加列のテーブル(おUNIQUEインデックス)は次のように計算されます:この場合はNULL両aとbがNULLでない場合は、このようにしてテーブルの主キーです。私はこの追加カラム"nullbuster"です。

alter table sandbox add nullbuster as 
  case when a is null or b is null then pk else null end;
create unique index sandbox_idx on sandbox(a,b,pk);

またこの例では、数回2002年頃にはなかなかないものではUsenetのmicrosoft.ます。sqlserver.プラグインです。きの討論をお探しの場合はgroups.google.com という言葉の"nullbuster".こんOracle利用な物質。

P.S. SQLサーバーに本ソリューションは、ほとんど気によるろ過方向であ

create unique index sandbox_idx on sandbox(a,b)
(where a is not null and b is not null);

スレッドで参照されることを示唆Oracleないこのオプションです。なにもなる可能性があるのはインデックスが別の代替?

create view sandbox_for_unique as
select a, b from sandbox
where a is not null and b is not null;

create index sandbox_for_unique_idx on sandbox_for_unique(a,b);

私はあなたができると思います。

のレコードは、しかし、私はあなたが2列に簡単な一意のインデックスを持っている場合、Oracleはそのように振る舞う理由を説明するために私の段落を残すだけのために:

列が一意にインデックス付けされている場合、

Oracleが2つ(1、NULL)の対を受け入れることはありません。

1およびヌルの対は、「刃先交換式」対であると考えられます。 2つのNULLのペアは、それはあなたが好きなようにあなたができるだけ多くのヌル、ヌルペアを挿入することができます理由です、インデックスを作成することはできません。

1を索引付けすることができるので、

(1、NULL)がインデックスされます。次回は再度、1は指数によってピックアップされ、一意性制約に違反している。(、nullの1)を挿入してみてください。

索引付けする値がないため、

(NULL、NULL)が索引付けされていません。それはユニーク制約に違反しない理由です。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top