Oracle 資料庫唯一約束中的NULL的處理

2021-12-29 21:49:17 字數 1831 閱讀 3530

根據null的定義,null表示的是未知,因此兩個null比較的結果既不相等,也不不等,結果仍然是未知。根據這個定義,多個null值的存在應該不違反唯一約束。

實際上oracle也是如此實現的:

sql> create table t (id number);

表已建立。

sql> alter table t add unique (id);

表已更改。

sql> insert into t values (1);

已建立 1 行。

sql> insert into t values (1);

insert into t values (1)

*第 1 行出現錯誤:

ora-00001: 違反唯一約束條件 (yangtk.sys_c007300)

sql> insert into t values (null);

已建立 1 行。

sql> insert into t values (null);

已建立 1 行。

sql> insert into t values (null);

已建立 1 行。

但是當唯一約束為復合欄位時,則情況發生了變化。根據oracle文件的描述,對於復合欄位的唯一約束,不為空字段的值是不能重複的。也就是說,如果兩個字段構成了乙個唯一約束,其中乙個欄位為空,那麼另乙個欄位的值不能出現重複。

sql> drop table t purge;

表已刪除。

sql> create table t (id number, id2 number);

表已建立。

sql> alter table t add unique (id, id2);

表已更改。 

sql> insert into t values (1, 1);

已建立 1 行。

sql> insert into t values (1, null);

已建立 1 行。 

sql> insert into t values (2, null);

已建立 1 行。

sql> insert into t values (1, null);

insert into t values (1, null)

*第 1 行出現錯誤:

ora-00001: 違反唯一約束條件 (yangtk.sys_c007301)

sql> insert into t values (null, null);

已建立 1 行。

sql> insert into t values (null, null);

已建立 1 行。

sql> insert into t values (null, null);

已建立 1 行。

對於全部為null的情況,仍然和單字段唯一約束一樣,不會造成重複,但是對於部分為null的情況,就如上面例子所示,只要其中不為null的部分發生了重複,oracle就認為約束發生了重複。

而這似乎和null的定義有所衝突,第一次看concept的時候一直沒有搞明白oracle為什麼這麼實現,不過這次再看concept的時候,已經想明白了。

由於oracle的唯一約束是依賴索引實現的,而oracle的btree索引又是不儲存null值的,所以鍵值全部為null的記錄不會記錄在索引中,因此也就不會違反唯一約束了,而對於部分為null的記錄,索引是要記錄數值的,因此一旦鍵值中非null部分發生了衝突,oracle就認為違反了的唯一約束。

oracle在這裡還是選擇了自己的方便的方法來實現,而沒有完全真正的根據null的定義去實現唯一約束。

Oracle資料庫的唯一約束

一 唯一約束的作用 保證字段值得唯一性。二 唯一約束和主鍵約束的區別 主鍵字段值必須是非空的。唯一約束允許有乙個空值。主鍵在每張表中只能有乙個。唯一約束在每張表中可以有多個。三 在建立表時設定唯一約束 1 在列級建立唯一約束 語法 create table table name column nam...

Oracle資料庫中違反唯一約束的處理

根據null的定義,null表示的是未知,因此兩個null比較的結果既不相等,也不不等,結果仍然是未知。根據這個定義,多個null值的存在應該不違反唯一約束。實際上oracle也是如此實現的 sql create table t id number 表已建立。sql alter table t ad...

oracle違反唯一約束

報錯資訊 nested exception is org.hibernate.exception.constraintviolationexception could not execute statement 背景 修改原有的邏輯,取消掉某個欄位的唯一約束。框架 spring data jpa 1...