【PK】Oracle 10g刪除主鍵約束後無法刪除唯一約束索引問題的模擬與分析
當先建立唯一約束後再建立主鍵約束的情況下,如果使用普通方法刪除主鍵約束後,唯一約束索引不會被刪除,這是Oracle 10g的一個PROBLEM。
本文透過一個實驗給大家演示一下這個問題的出現過程及處理方法。
【問題現象】
在10g環境下,在刪除主鍵約束後,在插入重複資料時候仍然報“ORA-00001: unique constraint (SEC.PK_T) violated”錯誤。
現象是主鍵約束已經刪除成功,但是唯一約束索引沒有級聯刪除。
【問題模擬】
1.建立表T
sec@ora10g> create table t (x int, y int);
Table created.
2.先建立惟一約束索引
sec@ora10g> create unique index pk_t on t (x);
Index created.
3.再建立主鍵約束
sec@ora10g> alter table t add (constraint pk_t primary key(x));
Table altered.
4.檢視約束資訊
sec@ora10g> col OWNER for a5
sec@ora10g> col CONSTRAINT_NAME for a30
sec@ora10g> col TABLE_NAME for a10
sec@ora10g> col INDEX_OWNER for a12
sec@ora10g> col INDEX_NAME for a10
sec@ora10g> select OWNER,CONSTRAINT_NAME,CONSTRAINT_TYPE,TABLE_NAME,INDEX_OWNER,INDEX_NAME from user_constraints where table_name = 'T';
OWNER CONSTRAINT_NAME C TABLE_NAME INDEX_OWNER INDEX_NAME
----- ------------------------------ - ---------- ------------ ----------
SEC PK_T P T SEC PK_T
5.檢視索引資訊
sec@ora10g> select INDEX_NAME,INDEX_TYPE,GENERATED from user_indexes;
INDEX_NAME INDEX_TYPE G
---------- --------------------------- -
PK_T NORMAL N
GENERATED欄位說明:
GENERATED VARCHAR2(1) Indicates whether the name of the index is system generated (Y) or not (N)
6.刪除主鍵約束
sec@ora10g> alter table t drop constraint pk_t cascade;
Table altered.
7.確認約束和索引刪除情況
sec@ora10g> select OWNER,CONSTRAINT_NAME,CONSTRAINT_TYPE,TABLE_NAME,INDEX_OWNER,INDEX_NAME from user_constraints where table_name = 'T';
no rows selected
sec@ora10g> select INDEX_NAME,INDEX_TYPE,GENERATED from user_indexes;
INDEX_NAME INDEX_TYPE G
---------- --------------------------- -
PK_T NORMAL N
可見,此時索引沒有被刪除。
因此,此時如果插入重複的資料,還是會報違反“約束”
sec@ora10g> insert into t values (1,1);
1 row created.
sec@ora10g> insert into t values (1,1);
insert into t values (1,1)
*
ERROR at line 1:
ORA-00001: unique constraint (SEC.PK_T) violated
【問題原因】
這個問題的原因可以參考MOS的[ID 309821.1]文章,文章中給出了具體原因。
Oracle 10G Does not Drop User Index Associated With Unique/Primary Key Constraints [ID 309821.1]
原來是Oracle在的10g版本中對內部函式"atbdui"進行了調整,導致在刪除約束的時候無法刪除使用者建立的索引。
這個現象被Oracle分類到了“PROBLEM”。
【處理方法】
在刪除約束的時候需要顯示的指定“drop index”選項來完成索引的級鏈刪除。
sec@ora10g> alter table t drop constraint pk_t cascade drop index;
Table altered.
經確認,約束和索引均被刪除後,嘗試插入兩條重複資料,成功。
sec@ora10g> select OWNER,CONSTRAINT_NAME,CONSTRAINT_TYPE,TABLE_NAME,INDEX_OWNER,INDEX_NAME from user_constraints where table_name = 'T';
no rows selected
sec@ora10g> select INDEX_NAME,INDEX_TYPE,GENERATED from user_indexes;
no rows selected
sec@ora10g> insert into t values (1,1);
1 row created.
sec@ora10g> insert into t values (1,1);
1 row created.
【BTW】如果之前建立的是普通索引,如果使用“cascade”選項,該索引也不會被刪除掉,實驗參考如下:
sec@ora10g> drop table t purge;
Table dropped.
sec@ora10g> create table t (x int, y int);
Table created.
sec@ora10g> create index pk_t on t (x);
Index created.
sec@ora10g> alter table t add (constraint pk_t primary key(x));
Table altered.
sec@ora10g> select OWNER,CONSTRAINT_NAME,CONSTRAINT_TYPE,TABLE_NAME,INDEX_OWNER,INDEX_NAME from user_constraints where table_name = 'T';
OWNER CONSTRAINT_NAME C TABLE_NAME INDEX_OWNER INDEX_NAME
----- ------------------------------ - ---------- ------------ ----------
SEC PK_T P T SEC PK_T
sec@ora10g> alter table t drop constraint pk_t cascade;
Table altered.
sec@ora10g> select OWNER,CONSTRAINT_NAME,CONSTRAINT_TYPE,TABLE_NAME,INDEX_OWNER,INDEX_NAME from user_constraints where table_name = 'T';
no rows selected
sec@ora10g> select INDEX_NAME,INDEX_TYPE,GENERATED from user_indexes;
INDEX_NAME INDEX_TYPE G
---------- --------------------------- -
PK_T NORMAL N
sec@ora10g> insert into t values (1,1);
1 row created.
sec@ora10g> insert into t values (1,1);
1 row created.
【小結】
實驗是答疑解惑的重要手段。當遇到一個問題後,我們應該以一種科學嚴謹的態度對待之,必有所獲。
Good luck.
secooler
10.03.01
-- The End --
本文透過一個實驗給大家演示一下這個問題的出現過程及處理方法。
【問題現象】
在10g環境下,在刪除主鍵約束後,在插入重複資料時候仍然報“ORA-00001: unique constraint (SEC.PK_T) violated”錯誤。
現象是主鍵約束已經刪除成功,但是唯一約束索引沒有級聯刪除。
【問題模擬】
1.建立表T
sec@ora10g> create table t (x int, y int);
Table created.
2.先建立惟一約束索引
sec@ora10g> create unique index pk_t on t (x);
Index created.
3.再建立主鍵約束
sec@ora10g> alter table t add (constraint pk_t primary key(x));
Table altered.
4.檢視約束資訊
sec@ora10g> col OWNER for a5
sec@ora10g> col CONSTRAINT_NAME for a30
sec@ora10g> col TABLE_NAME for a10
sec@ora10g> col INDEX_OWNER for a12
sec@ora10g> col INDEX_NAME for a10
sec@ora10g> select OWNER,CONSTRAINT_NAME,CONSTRAINT_TYPE,TABLE_NAME,INDEX_OWNER,INDEX_NAME from user_constraints where table_name = 'T';
OWNER CONSTRAINT_NAME C TABLE_NAME INDEX_OWNER INDEX_NAME
----- ------------------------------ - ---------- ------------ ----------
SEC PK_T P T SEC PK_T
5.檢視索引資訊
sec@ora10g> select INDEX_NAME,INDEX_TYPE,GENERATED from user_indexes;
INDEX_NAME INDEX_TYPE G
---------- --------------------------- -
PK_T NORMAL N
GENERATED欄位說明:
GENERATED VARCHAR2(1) Indicates whether the name of the index is system generated (Y) or not (N)
6.刪除主鍵約束
sec@ora10g> alter table t drop constraint pk_t cascade;
Table altered.
7.確認約束和索引刪除情況
sec@ora10g> select OWNER,CONSTRAINT_NAME,CONSTRAINT_TYPE,TABLE_NAME,INDEX_OWNER,INDEX_NAME from user_constraints where table_name = 'T';
no rows selected
sec@ora10g> select INDEX_NAME,INDEX_TYPE,GENERATED from user_indexes;
INDEX_NAME INDEX_TYPE G
---------- --------------------------- -
PK_T NORMAL N
可見,此時索引沒有被刪除。
因此,此時如果插入重複的資料,還是會報違反“約束”
sec@ora10g> insert into t values (1,1);
1 row created.
sec@ora10g> insert into t values (1,1);
insert into t values (1,1)
*
ERROR at line 1:
ORA-00001: unique constraint (SEC.PK_T) violated
【問題原因】
這個問題的原因可以參考MOS的[ID 309821.1]文章,文章中給出了具體原因。
Oracle 10G Does not Drop User Index Associated With Unique/Primary Key Constraints [ID 309821.1]
原來是Oracle在的10g版本中對內部函式"atbdui"進行了調整,導致在刪除約束的時候無法刪除使用者建立的索引。
這個現象被Oracle分類到了“PROBLEM”。
【處理方法】
在刪除約束的時候需要顯示的指定“drop index”選項來完成索引的級鏈刪除。
sec@ora10g> alter table t drop constraint pk_t cascade drop index;
Table altered.
經確認,約束和索引均被刪除後,嘗試插入兩條重複資料,成功。
sec@ora10g> select OWNER,CONSTRAINT_NAME,CONSTRAINT_TYPE,TABLE_NAME,INDEX_OWNER,INDEX_NAME from user_constraints where table_name = 'T';
no rows selected
sec@ora10g> select INDEX_NAME,INDEX_TYPE,GENERATED from user_indexes;
no rows selected
sec@ora10g> insert into t values (1,1);
1 row created.
sec@ora10g> insert into t values (1,1);
1 row created.
【BTW】如果之前建立的是普通索引,如果使用“cascade”選項,該索引也不會被刪除掉,實驗參考如下:
sec@ora10g> drop table t purge;
Table dropped.
sec@ora10g> create table t (x int, y int);
Table created.
sec@ora10g> create index pk_t on t (x);
Index created.
sec@ora10g> alter table t add (constraint pk_t primary key(x));
Table altered.
sec@ora10g> select OWNER,CONSTRAINT_NAME,CONSTRAINT_TYPE,TABLE_NAME,INDEX_OWNER,INDEX_NAME from user_constraints where table_name = 'T';
OWNER CONSTRAINT_NAME C TABLE_NAME INDEX_OWNER INDEX_NAME
----- ------------------------------ - ---------- ------------ ----------
SEC PK_T P T SEC PK_T
sec@ora10g> alter table t drop constraint pk_t cascade;
Table altered.
sec@ora10g> select OWNER,CONSTRAINT_NAME,CONSTRAINT_TYPE,TABLE_NAME,INDEX_OWNER,INDEX_NAME from user_constraints where table_name = 'T';
no rows selected
sec@ora10g> select INDEX_NAME,INDEX_TYPE,GENERATED from user_indexes;
INDEX_NAME INDEX_TYPE G
---------- --------------------------- -
PK_T NORMAL N
sec@ora10g> insert into t values (1,1);
1 row created.
sec@ora10g> insert into t values (1,1);
1 row created.
【小結】
實驗是答疑解惑的重要手段。當遇到一個問題後,我們應該以一種科學嚴謹的態度對待之,必有所獲。
Good luck.
secooler
10.03.01
-- The End --
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/519536/viewspace-628313/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 解決資料庫的索引亂碼問題,先刪除外來鍵約束,再刪除主鍵約束及其索引資料庫索引
- 新增/刪除約束(Oracle)Oracle
- Oracle主鍵約束、唯一鍵約束、唯一索引的區別(轉)Oracle索引
- Mysql-基本練習(06-唯一約束、外來鍵約束、新增、刪除單列)MySql
- 批量刪除MSSQL 中主外來鍵約束SQL
- mysql 刪除老是報外來鍵約束MySql
- 解決無法刪除表,提示被外來鍵約束引用
- 資料完整性約束:主鍵、外來鍵、各種約束的建立刪除語句
- mysql中外來鍵約束級聯更新與刪除MySql
- 【INDEX】Oracle中主鍵、唯一約束與唯一索引之區別IndexOracle索引
- 利用虛擬列實現虛擬刪除的主外來鍵約束
- 生成指令碼,得到所有表的外來鍵約束,然後刪除並重建這些約束指令碼
- mysql刪除主鍵索引,刪除索引語法MySql索引
- 如何解決邏輯刪除與資料庫唯一約束衝突資料庫
- Sqlserver中所有約束的型別,建立、修改與刪除SQLServer型別
- 【Foreign Key】Oracle外來鍵約束三種刪除行為Oracle
- ORACLE: 查詢(看)表的主鍵、外來鍵、唯一性約束和索引Oracle索引
- Oracle刪除主鍵保留索引的方法Oracle索引
- Oracle定義約束 外來鍵約束Oracle
- [求助][資料庫]表間約束的刪除完整性?資料庫
- 查詢(看)表的主鍵、外來鍵、唯一性約束和索引索引
- oracle鍵約束控制Oracle
- 請求結束後刪除檔案
- Javaweb-約束-外來鍵約束JavaWeb
- sql server中預設約束的通用sql指令碼的刪除方法SQLServer指令碼
- rhel4 mysql5.1 索引index_約束constraint建立_刪除_查詢MySql索引IndexAI
- 遷移後處理外來鍵約束的問題
- SQL的主鍵和外來鍵約束SQL
- Oracle唯一約束中NULL的處理OracleNull
- Oracle約束Oracle
- oracle 約束Oracle
- 無順序約束的字串匹配問題字串匹配
- 【SQL】15 SQL 約束(Constraints)、NOT NULL 約束、UNIQUE 約束、PRIMARY KEY 約束、FOREIGN KEY 約束、CHECK 約束、DEFAULT約束SQLAINull
- 資料庫約束 主鍵-唯一性-Check-外來鍵資料庫
- MyBatisPlus解決邏輯刪除與唯一索引的相容問題MyBatis索引
- 唯一性約束和唯一性索引的區別索引
- PostgreSQL唯一約束如何使用?SQL
- SQL Server唯一約束的使用SQLServer