在看Oracle約束時,看到ENABLE NOVALIDATE,意思是對自現在起及以後的資料啟用約束,但是不管以前的資料怎樣。
不過在實驗的時候卻出了一點小問題:
SQL> create table dept as select * from scott.dept where 1=2;</p><p>Table created</p><p>SQL> insert into dept select * from scott.dept where deptno=10;</p><p>1 row inserted</p><p>SQL> insert into dept select * from scott.dept where deptno=10;</p><p>1 row inserted</p><p>SQL> commit;</p><p>Commit complete</p><p>SQL> ALTER TABLE dept ADD (UNIQUE(deptno) ENABLE NOVALIDATE);</p><p>ALTER TABLE dept ADD (UNIQUE(deptno) ENABLE NOVALIDATE)</p><p>ORA-02299: cannot validate (XXPO.SYS_C00830643) - duplicate keys found</p><p>SQL>
Google一下,發現原來在建立沒有延時的UNIQUE或者PRIMARY KEY時會自動去建立一個唯一性索引。(By default a non-deferrable UNIQUE or PRIMARY KEY constraint will attempt to create a unqiue index. http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:8806498660292)
加上DEFERRABLE關鍵字,問題成功解決:
SQL> ALTER TABLE dept ADD (UNIQUE(deptno) DEFERRABLE ENABLE NOVALIDATE);</p><p>Table altered</p><p>SQL>
asktom上還有另外一種通過自己手動先建立一個普通索引的解決方案,有興趣的同學可以看看。
Ref:http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:8806498660292