Skip to Main Content

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, atul.

Asked: September 27, 2002 - 9:43 pm UTC

Last updated: September 27, 2002 - 9:43 pm UTC

Version: 8.0.4

Viewed 1000+ times

You Asked

Sir,

I'm facing very confusing situation...

I have a table test having two indexes on it...
1)PK_TEST (EMPNO,NAME,ATT) is primaty key
2)TEST_IND(EMPNO,ATT,NAME) Is non-unique index...

i want to drop index TEST_IND...
when i give command to drop TEST_IND it gives error saying,

ORA-02429: cannot drop index used for enforcement of unique/primary key

But test_ind is non-unique index and not a primary key on a table..

also starnge is when we see in user_indexes it doesn't show PK_TEST index it only shows TEST_IND..

But in constraints it shows primary key constarint..

Why this has happened and how to proceed..

Thanks.
atul



and Tom said...

There are two concepts to understand here:

A primary key constraint can be enforced using ANY index (unique or not). In fact, a deferrable primary key constraint can ONLY use a non-unique index.

The order of the columns in the index are not material, in fact, the NUMBER of columns in the index may be greater then the number of columns in the primary key. It is only necessary that that "leading edge of the index" contains the primary key columns.


You created TEST_IND. Then you created another index PK_TEST. THEN you added a constraint PK_TEST. This constraint went to the data dictionary and found the FIRST index that it was happy with -- one that it could use to enforce the constraint. That was TEST_IND in this case. Consider:



ops$tkyte@ORA806.WORLD> create table t ( empno int, name int, att int );

Table created.

ops$tkyte@ORA806.WORLD>
ops$tkyte@ORA806.WORLD> create index test_ind on t(empno, att, name);

Index created.

ops$tkyte@ORA806.WORLD> create index pk_test on t(empno,name,att);

Index created.

ops$tkyte@ORA806.WORLD>
ops$tkyte@ORA806.WORLD> alter table t add constraint t_pk primary key(empno,name,att);

Table altered.

ops$tkyte@ORA806.WORLD>
ops$tkyte@ORA806.WORLD> drop index test_ind;
drop index test_ind
*
ERROR at line 1:
ORA-02429: cannot drop index used for enforcement of unique/primary key



Now, in your case, all you need to do is drop PK_TEST:

ops$tkyte@ORA806.WORLD> drop index pk_test;

Index dropped.


and you have the set of indexes you want (an index on empno, att, name). Alternatively, you can

o drop the constraint pk_test
o drop the index test_ind
o create the constraint pk_test and it'll now "kidnap" the pk_test index.


Is this answer out of date? If it is, please let us know via a Comment