Skip to Main Content
  • Questions
  • ORA-14130: UNIQUE constraints mismatch ... got the solution ...please review

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, sj.

Asked: July 13, 2001 - 5:21 pm UTC

Last updated: December 17, 2012 - 3:56 pm UTC

Version: 8.1.7

Viewed 10K+ times! This question is

You Asked

</code> http://asktom.oracle.com/pls/ask/f?p=4950:9:::NO::F4950_P9_ORIG,F4950_P9_DISPLAYID:Y,963478374614 <code>


Finally Tom, I understood what you were saying..


I did the following

create table emppart
( EMPNO NUMBER(4) ,
ENAME VARCHAR2(10),
JOB VARCHAR2(9),
MGR NUMBER(4),
HIREDATE DATE,
SAL NUMBER(7,2),
COMM NUMBER(7,2),
DEPTNO NUMBER(2))
partiton by range(hiredate)
(partition p1 values less than (to_date('07-07-2001','dd-mm-yyyy')),
partition p2 values less than (MAXVALUE))

create index idx_emppart on emppart(empno,hiredate,deptno) local;


create table emp
( EMPNO NUMBER(4) ,
ENAME VARCHAR2(10),
JOB VARCHAR2(9),
MGR NUMBER(4),
HIREDATE DATE,
SAL NUMBER(7,2),
COMM NUMBER(7,2),
DEPTNO NUMBER(2))

create index idx_emp on emppart(empno,hiredate,deptno);




alter table emppart exchange partition p1 with emp including indexes;


'IT WORKED......'

I them tried...UNIZUE INDEXES

drop index idx_emp;
drop index idx_emppart;

create UNIQUE index idx_emp on emppart(empno,hiredate,deptno);
create index idx_emppart on emppart(empno,hiredate,deptno) local;

alter table emppart exchange partition p1 with emp including indexes;

'IT WORKED..'

TOM,

basically, I haved avoided using primary key on the partitioned table.. and created a UNIQUE indexes..

TOM, can you explain to me what is the difference of declaring a primary key , or instead of doing that creating a UNIQUE index with the same columns..

i.e. PRIMARY KEY Vs Unique index..


Thank you very much .













and Tom said...

You only half got it, close but no cigar.

there isn't any difference except that one is a primary key (includes not null constraints) and the other isn't a primary key.

The only thing to consider here is the type of index used. LOCAL or GLOBAL. You made the primary key be included in the partition key -- now you can use a primary key IF you specify that a local index is to be used.

After fixing syntax in your example, we have:

ops$tkyte@ORA815> create table emppart
2 ( EMPNO NUMBER(4) ,
3 ENAME VARCHAR2(10),
4 JOB VARCHAR2(9),
5 MGR NUMBER(4),
6 HIREDATE DATE,
7 SAL NUMBER(7,2),
8 COMM NUMBER(7,2),
9 DEPTNO NUMBER(2))
10 partition by range(hiredate)
11 (partition p1 values less than (to_date('07-07-2001','dd-mm-yyyy')),
12 partition p2 values less than (MAXVALUE))
13 /
Table created.

ops$tkyte@ORA815> alter table emppart add constraint emppart_pk
2 primary key ( empno, hiredate, deptno )
3 using INDEX local
4 /
Table altered.

ops$tkyte@ORA815> create table emp
2 ( EMPNO NUMBER(4) ,
3 ENAME VARCHAR2(10),
4 JOB VARCHAR2(9),
5 MGR NUMBER(4),
6 HIREDATE DATE,
7 SAL NUMBER(7,2),
8 COMM NUMBER(7,2),
9 DEPTNO NUMBER(2))
10 /
Table created.

ops$tkyte@ORA815> alter table emp add constraint emp_pk primary key (empno, hiredate, deptno )
2 /
Table altered.

ops$tkyte@ORA815> alter table emppart exchange partition p1 with table emp including indexes;

Table altered.


there you go, exchanged a table with a partition of a partitioned table that had a primary key including indexes.


Rating

  (9 ratings)

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

Comments

difference between unique key and unique index

A reader, July 24, 2002 - 5:58 pm UTC

tom,
is there a difference between creating an unique index on a,b,c columns of table t

and

creating unique key on the table t with the columns a,b and c.

does the unique index enforce the uniqueness on the columns or we have to create the unique seperately i need not create unique key

i don't see any key in constraints table user_constraints when i create an unique index.

in the same way vice versa

the same way

Tom Kyte
July 24, 2002 - 11:04 pm UTC

YES.

a unique constraint is used by the optimizer with query rewrites and other features.

a unique index is not used by the optimizer for query rewrites.

see
</code> http://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:3051352977204 <code>
for details.

Question from Answer

Sajid, July 24, 2002 - 11:51 pm UTC

Sir I want to know details of function
>>partiton by range(hiredate)<<
Please explian it.


Tom Kyte
July 25, 2002 - 6:43 am UTC

In general you want to read:

</code> http://docs.oracle.com/docs/cd/A87860_01/doc/server.817/a76965/toc.htm

from cover to cover.  The syntax you ask about is part of partitioning -- the ability to split a big object into lots of smaller ones.  The chapter for that one is:

http://docs.oracle.com/docs/cd/A87860_01/doc/server.817/a76965/c09parti.htm#436962 <code>

alter table... exchange partition

Andy, October 28, 2003 - 6:43 pm UTC


Hi Tom,

I am loading data into a temp table T and then exchanging the temp table with a partitioned table A. The temp table is an exact replica of the partitioned table A. Infact, I generated DDL from table A and then created T from it. I see no difference between A and T.

But, when I do an EXCHANGE PARTITION, it fails and errors out with ORA-14118 "CHECK constraint mismatch in ALTER TABLE EXCHANGE PARTITION". Why does this happen?

Both A and T have 8 check constraints each and all were enabled. When we disabled all the check constraints, it worked fine.

My question is :

1. Is it absolutely neccessary to disable CHECK constraints on both the tables A and T before exchanging partitions?

2. Can a table have a PRIMARY KEY constraint and a NOT NULL constraint in the same column ?

Thanks

Anand

Tom Kyte
October 28, 2003 - 9:12 pm UTC

hows about an example????????? like I give all of the time??



CHECK constraint mismatch in ALTER TABLE EXCHANGE PARTITION

karma, December 22, 2003 - 5:10 pm UTC

I am getting the error "ORA-14118: CHECK constraint mismatch in ALTER TABLE EXCHANGE PARTITION". I have one table that is partioned and one that is not partitioned and all i do is exchange partition as :
ALTER TABLE RW1.AB_DET_HST EXCHANGE PARTITION PART_BAL_DET_HST_20031202 WITH TABLE RW1.AB_DET ;

Here is table structure : Non Partioned Table
CREATE TABLE RW1.AB_DET
(
F_FIRM_C VARCHAR2(4 BYTE) NOT NULL,
F_BR_C VARCHAR2(3 BYTE) NOT NULL,
F_BA_C VARCHAR2(6 BYTE) NOT NULL,
EFF_D DATE NOT NULL,
ACCT_TY_C VARCHAR2(1 BYTE) NOT NULL,
MKT_VALU_A NUMBER(13,2) NULL,
LOAN_A NUMBER(11,2) NULL,
PRTN_ID VARCHAR2(6 BYTE) NULL,
INSERT_TMST DATE NULL,
UPDATE_TMST DATE NULL
)
LOGGING
NOCACHE
NOPARALLEL
/

CREATE UNIQUE INDEX RW1.ABDET_PK ON RW1.AB_DET
(F_FIRM_C, F_BR_C, F_BA_C, ACCT_TY_C, EFF_D)
LOGGING
NOPARALLEL
/

ALTER TABLE RW1.AB_DET ADD (
CONSTRAINT ABDET_PK PRIMARY KEY (F_FIRM_C, F_BR_C, F_BA_C, ACCT_TY_C, EFF_D))
/

Here is script for partitioned table :

CREATE TABLE RW1.AB_DET_HST
(
F_FIRM_C VARCHAR2(4 BYTE) CONSTRAINT SYS_C003290 NOT NULL,
F_BR_C VARCHAR2(3 BYTE) CONSTRAINT SYS_C003291 NOT NULL,
F_BA_C VARCHAR2(6 BYTE) CONSTRAINT SYS_C003292 NOT NULL,
EFF_D DATE CONSTRAINT SYS_C003293 NOT NULL,
ACCT_TY_C VARCHAR2(1 BYTE) CONSTRAINT SYS_C003294 NOT NULL,
MKT_VALU_A NUMBER(13,2) NULL,
LOAN_A NUMBER(11,2) NULL,
PRTN_ID VARCHAR2(6 BYTE) NULL,
INSERT_TMST DATE NULL,
UPDATE_TMST DATE NULL
)
PARTITION BY RANGE (EFF_D)
(
PARTITION PART_BAL_DET_HST_20031120 VALUES LESS THAN (TO_DATE(' 2003-11-20 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
LOGGING
NOCOMPRESS,
PARTITION PART_BAL_DET_HST_20031202 VALUES LESS THAN (TO_DATE(' 2003-12-03 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
LOGGING
NOCOMPRESS
)
NOCACHE
NOPARALLEL
/

CREATE UNIQUE INDEX RW1.ABDETH_PK ON RW1.AB_DET_HST
(F_FIRM_C, F_BR_C, F_BA_C, ACCT_TY_C, EFF_D)
LOGGING
NOPARALLEL
/

ALTER TABLE RW1.AB_DET_HST ADD (
CONSTRAINT ABDETH_PK PRIMARY KEY (F_FIRM_C, F_BR_C, F_BA_C, ACCT_TY_C, EFF_D))
/

What am i doing wrong that is giving me error :
ORA-14118: CHECK constraint mismatch in ALTER TABLE EXCHANGE PARTITION

What is correct way of doing it ?

Thanks


Tom Kyte
December 22, 2003 - 6:41 pm UTC

works for me -- you must have 9ir2 like me (nocompress) so.... you must have some other constraint out there your example doesn't show us

ops$tkyte@ORA9IR2> drop TABLE AB_DET;
 
Table dropped.
 
ops$tkyte@ORA9IR2> CREATE TABLE AB_DET
  2  (
  3    F_FIRM_C  VARCHAR2(4 BYTE)                 NOT NULL,
  4    F_BR_C  VARCHAR2(3 BYTE)                 NOT NULL,
  5    F_BA_C  VARCHAR2(6 BYTE)                 NOT NULL,
  6    EFF_D        DATE                             NOT NULL,
  7    ACCT_TY_C    VARCHAR2(1 BYTE)                 NOT NULL,
  8    MKT_VALU_A   NUMBER(13,2)                         NULL,
  9    LOAN_A       NUMBER(11,2)                         NULL,
 10    PRTN_ID      VARCHAR2(6 BYTE)                     NULL,
 11    INSERT_TMST  DATE                                 NULL,
 12    UPDATE_TMST  DATE                                 NULL
 13  )
 14  LOGGING
 15  NOCACHE
 16  NOPARALLEL
 17  /
 
Table created.
 
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> CREATE UNIQUE INDEX ABDET_PK ON AB_DET
  2  (F_FIRM_C, F_BR_C, F_BA_C, ACCT_TY_C, EFF_D)
  3  LOGGING
  4  NOPARALLEL
  5  /
 
Index created.
 
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> ALTER TABLE AB_DET ADD (
  2    CONSTRAINT ABDET_PK PRIMARY KEY (F_FIRM_C, F_BR_C, F_BA_C, ACCT_TY_C, EFF_D))
  3  /
 
Table altered.
 
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> drop TABLE AB_DET_HST;
 
Table dropped.
 
ops$tkyte@ORA9IR2> CREATE TABLE AB_DET_HST
  2  (
  3    F_FIRM_C  VARCHAR2(4 BYTE) CONSTRAINT SYS_C003290 NOT NULL,
  4    F_BR_C  VARCHAR2(3 BYTE) CONSTRAINT SYS_C003291 NOT NULL,
  5    F_BA_C  VARCHAR2(6 BYTE) CONSTRAINT SYS_C003292 NOT NULL,
  6    EFF_D        DATE CONSTRAINT SYS_C003293      NOT NULL,
  7    ACCT_TY_C    VARCHAR2(1 BYTE) CONSTRAINT SYS_C003294 NOT NULL,
  8    MKT_VALU_A   NUMBER(13,2)                         NULL,
  9    LOAN_A       NUMBER(11,2)                         NULL,
 10    PRTN_ID      VARCHAR2(6 BYTE)                     NULL,
 11    INSERT_TMST  DATE                                 NULL,
 12    UPDATE_TMST  DATE                                 NULL
 13  )
 14  PARTITION BY RANGE (EFF_D)
 15  (
 16    PARTITION PART_BAL_DET_HST_20031120 VALUES LESS THAN (TO_DATE(' 2003-11-20 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
 17      LOGGING
 18      NOCOMPRESS,
 19    PARTITION PART_BAL_DET_HST_20031202 VALUES LESS THAN (TO_DATE(' 2003-12-03 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
 20      LOGGING
 21      NOCOMPRESS
 22  )
 23  NOCACHE
 24  NOPARALLEL
 25  /
 
Table created.
 
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> CREATE UNIQUE INDEX ABDETH_PK ON AB_DET_HST
  2  (F_FIRM_C, F_BR_C, F_BA_C, ACCT_TY_C, EFF_D)
  3  LOGGING
  4  NOPARALLEL
  5  /
 
Index created.
 
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> ALTER TABLE AB_DET_HST ADD (
  2    CONSTRAINT ABDETH_PK PRIMARY KEY (F_FIRM_C, F_BR_C, F_BA_C, ACCT_TY_C, EFF_D))
  3  /
 
Table altered.
 
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> ALTER TABLE AB_DET_HST       EXCHANGE PARTITION PART_BAL_DET_HST_20031202 WITH
  2  TABLE AB_DET
  3  /
 
Table altered.
 
 

i thought i understood ora 14130

martina, November 23, 2009 - 10:54 am UTC

Hello Tom,

Every week the oldest Partition is to be pruned, that is done with 'alter table xy exchange partition xyz with table wxyz including indexes'. A new column was added to the primary key. the pk is 11 Columns wide.
and then it throws an ora 14130.

There were 4 of us checking user_constraints, user_cons_columns, user_ind_columns and user_tab_columns. we cannot find any differences. the problem is all this is done by packages (i wrote)and the table i am talking of is a little table. there are bigger ones to come. if we recreate the indices on the partitioned table it works. if i set the pk-sonstraints to novalidate it works.

when i take the commands out of the package trying to get a testcase it always works. we are using fgac but not on the tables involved. we upgraded from V9 to V10 lately. Is there any hint you have for us?

thank you
martina




Tom Kyte
November 23, 2009 - 5:03 pm UTC

you'd have to give me a concrete example to work with. You say "a new column was added to the primary key", but not how or why this fact would be relevant. It must be...


14130 changed to 14098

martina, November 25, 2009 - 11:44 am UTC

Hello Tom,

I think I succeded in constructing an example. The story is that we added a column init_plunr to the table and primary key and now the alter table exchange partition fails with ora 14130 at some databases (at one it does not fail). And we cannot find any reasons for the failure in the data dictionary.

the table:
INFO/INFO_PROD> desc scaart_wo
 Name                                                              Null?    Type
 ----------------------------------------------------------------- -------- --------------------------------------------
 ARTNR                                                             NOT NULL NUMBER(6)
 FIRMA                                                             NOT NULL CHAR(2)
 PERIODE                                                           NOT NULL CHAR(6)
 WAGR                                                              NOT NULL CHAR(5)
 RGM                                                               NOT NULL CHAR(4)
 WERBEKZ                                                           NOT NULL CHAR(1)
 LIEFNR                                                            NOT NULL NUMBER(6)
 ALIAS                                                             NOT NULL VARCHAR2(13)
 VK_MGE                                                            NOT NULL NUMBER(12,2)
 BRUTTO_VKW                                                        NOT NULL NUMBER(16,2)
 NETTO_VKW                                                         NOT NULL NUMBER(16,2)
 EKW                                                               NOT NULL NUMBER(16,2)
 WAEHRG                                                            NOT NULL VARCHAR2(3)
 AKTION_ID                                                         NOT NULL NUMBER
 AKTION_TYP                                                        NOT NULL VARCHAR2(2)
 RETOUR                                                            NOT NULL VARCHAR2(1)
 AKTION_MGE                                                                 NUMBER
 DEKW                                                                       NUMBER
 ANZ_BON                                                                    NUMBER
 MGE_GE                                                                     NUMBER
 INIT_PLUNR                                                                 VARCHAR2(30)
 INIT_MENGE                                                                 NUMBER

INFO/INFO_PROD> 



the script i constructed:
NFO/INFO_PROD> sta all.y
INFO/INFO_PROD> drop table mpa_test ;

Table dropped.

INFO/INFO_PROD> create table mpa_test
  2  partition by range (periode)
  3  (partition wo_200943 values less than ('200944'))
  4  as
  5  select * from scaart_wo partition (wo_200943) where rownum < 100000
  6  ;

Table created.

INFO/INFO_PROD> begin
  2  execute immediate 'create index mpa_test_f1 on mpa_test
  3                     ( CASE  WHEN AKTION_ID>0 THEN AKTION_ID END)
  4         tablespace &&ind nologging ';
  5  execute immediate 'create index mpa_test_i1 on mpa_test
  6                     (aktion_typ, firma)
  7         tablespace &&ind nologging ';
  8  execute immediate 'alter table mpa_test add constraint FKt30944 foreign key ( ARTNR,FIRMA ) references ARTST ( ARTNR,FIRMA) novalidate' ;
  9  execute immediate 'alter table mpa_test add constraint FKt30945 foreign key ( LIEFNR,FIRMA ) references LIFST ( LIEFNR,FIRMA) novalidate';
 10  execute immediate 'create unique index mpa_test_pk on mpa_test
 11                    (ARTNR,FIRMA,WAGR,RGM,WERBEKZ,LIEFNR,ALIAS,AKTION_ID,RETOUR,INIT_PLUNR,PERIODE)
 12                     tablespace &&ind nologging unusable compress 3 local';
 13  execute immediate 'alter index mpa_test_pk rebuild partition wo_200943 ';
 14  execute immediate 'alter table mpa_test add constraint mpa_test_pk primary key
 15                    (ARTNR,FIRMA,WAGR,RGM,WERBEKZ,LIEFNR,ALIAS,AKTION_ID,RETOUR,INIT_PLUNR,PERIODE)'
 16         ;
 17  end;
 18  .
INFO/INFO_PROD> /
old   4:        tablespace &&ind nologging ';
new   4:        tablespace INDU nologging ';
old   7:        tablespace &&ind nologging ';
new   7:        tablespace INDU nologging ';
old  12:                    tablespace &&ind nologging unusable compress 3 local';
new  12:                    tablespace INDU nologging unusable compress 3 local';

PL/SQL procedure successfully completed.

INFO/INFO_PROD> begin
  2  execute immediate 'alter table mpa_test modify init_plunr null ';
  3  end;
  4  .
INFO/INFO_PROD> /
begin
*
ERROR at line 1:
ORA-01451: column to be modified to NULL cannot be modified to NULL
ORA-06512: at line 2


INFO/INFO_PROD>
INFO/INFO_PROD> drop table mpa_t ;

Table dropped.

INFO/INFO_PROD> begin
  2  execute immediate 'create table mpa_t as select * from mpa_test where mod(artnr,10) = 0';
  3  execute immediate 'create index mpa_t_f1 on mpa_t
  4                     ( CASE  WHEN AKTION_ID>0 THEN AKTION_ID END)
  5         tablespace &&ind nologging ';
  6  execute immediate 'create index mpa_t_i1 on mpa_t
  7                     (aktion_typ, firma)
  8         tablespace &&ind nologging ';
  9  execute immediate 'alter table mpa_t add constraint FK30944 foreign key ( ARTNR,FIRMA ) references ARTST ( ARTNR,FIRMA) novalidate' ;
 10  execute immediate 'alter table mpa_t add constraint FK30945 foreign key ( LIEFNR,FIRMA ) references LIFST ( LIEFNR,FIRMA) novalidate';
 11  execute immediate 'create unique index mpa_t_pk on mpa_t
 12         (ARTNR,FIRMA,WAGR,RGM,WERBEKZ,LIEFNR,ALIAS,AKTION_ID,RETOUR,INIT_PLUNR,PERIODE)
 13         tablespace &&ind nologging compress 3 ';
 14  execute immediate 'alter table mpa_t add constraint mpa_t_pk primary key
 15         (ARTNR,FIRMA,WAGR,RGM,WERBEKZ,LIEFNR,ALIAS,AKTION_ID,RETOUR,INIT_PLUNR,PERIODE)'
 16         ;
 17  end;
 18  .
INFO/INFO_PROD> /
old   5:        tablespace &&ind nologging ';
new   5:        tablespace INDU nologging ';
old   8:        tablespace &&ind nologging ';
new   8:        tablespace INDU nologging ';
old  13:        tablespace &&ind nologging compress 3 ';
new  13:        tablespace INDU nologging compress 3 ';

PL/SQL procedure successfully completed.

INFO/INFO_PROD> begin
  2  execute immediate 'alter table mpa_t modify init_plunr null ';
  3  end;
  4  .
INFO/INFO_PROD> /
begin
*
ERROR at line 1:
ORA-01451: column to be modified to NULL cannot be modified to NULL
ORA-06512: at line 2


INFO/INFO_PROD> begin
  2  -- pl_manage.drop_policy(user,'mpa_test');
  3  execute immediate 'alter table mpa_test exchange partition wo_200943 with table mpa_t including indexes ';
  4  -- pl_manage.restore_policy(user,'mpa_test');
  5  end;
  6  .
INFO/INFO_PROD> /
begin
*
ERROR at line 1:
ORA-14098: index mismatch for tables in ALTER TABLE EXCHANGE PARTITION
ORA-06512: at line 3


the error number changed but I am positive it is related.
I think we should enter a SR.

Best regards,
martina
Tom Kyte
November 28, 2009 - 10:30 am UTC

what is the meaning of the alter that fails - is it relevant?


give a script that *anyone on the planet* can run - from soup to nuts, create table (no tablespaces) for everything. No tablespace references, just use defaults - give us something we can cut and paste and observe - removing everything that is not relevant - like your alter null statements - since they do not work - why are they there at all?

Make it as tiny as possible.

ORA-14130 Problem

Florian, December 10, 2009 - 1:56 am UTC

Hello Tom;

One word before my question. Your site is great and very helpful. I have looked up many things and learned a lot of new stuff about ORACLE. Thank you :)

In the above post my colleague was asking for a table exchanged that failed because of an ORA-14130. Now we have changed some code of the skript so that it can be run anywhere:

set echo on

drop table mpa_test ;

-- CREATE BASE HELPER TABLE
create table mpa_test (
 ARTNR       NUMBER(6)    NOT NULL
,FIRMA       CHAR(2)      NOT NULL
,PERIODE     CHAR(6)      NOT NULL
,WAGR        CHAR(5)      NOT NULL
,RGM         CHAR(4)      NOT NULL
,WERBEKZ     CHAR(1)      NOT NULL
,LIEFNR      NUMBER(6)    NOT NULL
,ALIAS       VARCHAR2(13) NOT NULL
,VK_MGE      NUMBER(12,2) NOT NULL
,BRUTTO_VKW  NUMBER(16,2) NOT NULL
,NETTO_VKW   NUMBER(16,2) NOT NULL
,EKW         NUMBER(16,2) NOT NULL
,WAEHRG      VARCHAR2(3)  NOT NULL
,AKTION_ID   NUMBER       NOT NULL
,AKTION_TYP  VARCHAR2(2)  NOT NULL
,RETOUR      VARCHAR2(1)  NOT NULL
,AKTION_MGE  NUMBER
,MGE_GE      NUMBER
,ANZ_BON     NUMBER
,DEKW        NUMBER
)
partition by range (periode)
(partition wo_200943 values less than ('200944'));


-- INSERT AT LEAST ONE ROW INTO BASE HELPER TABLE
insert into mpa_test select rownum, '00', '200943', '1111', 'qwer', 'J', 123123, 'qwertzqwertzq'
                            ,1, 1, 1, 1, 'EUR', 1, 'QQ', 'J', 1, 1, 1, 1
                       from user_objects
                       where rownum < 2;

-- UNIQUE (PRIMARY KEY) INDEX ON BASE HELPER TABLE
create unique index mpa_test_pk on mpa_test
  (ARTNR,FIRMA,PERIODE,WAGR,RGM,WERBEKZ,LIEFNR,ALIAS,AKTION_ID,RETOUR)
  nologging local;

alter table mpa_test add constraint mpa_test_pk primary key
  (ARTNR,FIRMA,PERIODE,WAGR,RGM,WERBEKZ,LIEFNR,ALIAS,AKTION_ID,RETOUR);


-- INDEX 1 ON BASE HELPER TABLE
create index mpa_test_i1 on mpa_test
   (aktion_typ, firma)
   nologging local;


-- FUNCTION BASED INDEX 1 ON BASE HELPER TABLE
create index mpa_test_f1 on mpa_test
   ( CASE  WHEN AKTION_ID>0 THEN AKTION_ID END)
   nologging local;


-- ADD INIT_PLUNR AND INIT_MENGE TO BASE HELPER TABLE
alter table mpa_test add init_plunr varchar2(30);
alter table mpa_test add init_menge number;


-- UPDATE NULL COLUMNS IN BASE HELPER TABLE
update mpa_test set init_plunr = '#' where init_plunr is null;


-- NEW UNIQUE (PRIMARY KEY) INDEX ON BASE HELPER TABLE
alter table mpa_test drop primary key drop index;

create unique index mpa_test_pk on mpa_test
  (ARTNR,FIRMA,WAGR,RGM,WERBEKZ,LIEFNR,ALIAS,AKTION_ID,RETOUR,INIT_PLUNR,PERIODE)
  nologging unusable compress 3 local;

alter index mpa_test_pk rebuild partition wo_200943;

alter table mpa_test add constraint mpa_test_pk primary key
  (ARTNR,FIRMA,WAGR,RGM,WERBEKZ,LIEFNR,ALIAS,AKTION_ID,RETOUR,INIT_PLUNR,PERIODE);


drop table mpa_t ;

-- CREATE EXCHANGE HELPER TABLE
create table mpa_t as select * from mpa_test where 1 = 2;

-- UNIQUE (PRIMARY KEY) INDEX ON EXCHANGE HELPER TABLE
create unique index mpa_t_pk on mpa_t
  (ARTNR,FIRMA,WAGR,RGM,WERBEKZ,LIEFNR,ALIAS,AKTION_ID,RETOUR,INIT_PLUNR,PERIODE)
  nologging compress 3;

alter table mpa_t add constraint mpa_t_pk primary key
  (ARTNR,FIRMA,WAGR,RGM,WERBEKZ,LIEFNR,ALIAS,AKTION_ID,RETOUR,INIT_PLUNR,PERIODE);


-- FUNCTION BASED INDEX 1 ON EXCHANGE HELPER TABLE
create index mpa_t_f1 on mpa_t
  ( CASE  WHEN AKTION_ID>0 THEN AKTION_ID END)
  nologging;


-- INDEX 1 ON EXCHANGE HELPER TABLE
create index mpa_t_i1 on mpa_t
  (aktion_typ, firma)
  nologging;


-- EXCHANGE BASE HELPER TABLE WITH EXCHANGE HELPER TABLE
alter table mpa_test exchange partition wo_200943 with table mpa_t including indexes;

select count(*) from mpa_test;
select count(*) from mpa_t;


When I run this code I'm getting the following:

alter table mpa_test exchange partition wo_200943 with table mpa_t including indexes
*
ERROR at line 1:
ORA-14130: UNIQUE constraints mismatch in ALTER TABLE EXCHANGE PARTITION


However the USER_IND_COLUMNS Views says, that the indexes are matching exactly.

When there are no data within the MPA_TEST table the exchange works, as well if we skip the function-based index (mpa_test_f1). The problem began with the addition of the INIT_PLUNR column.

We are using:

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi
PL/SQL Release 10.2.0.4.0 - Production
CORE    10.2.0.4.0      Production
TNS for HPUX: Version 10.2.0.4.0 - Production
NLSRTL Version 10.2.0.4.0 - Production



Thanks in advance.

Regards,
Florian
Tom Kyte
December 10, 2009 - 2:52 pm UTC

Ok, that is a strange one

It does not reproduce in 11gr1 or 11gr2

and it does take all of that to do it. add columns rather than have them in the create table, etc...

well, I'll have to ask you to take this one to support and have them triage it - a bug was fixed between 10.2 and 11.1 - but I don't know which one it was...

Whats the Patch Number to be installed on 10.2.0.4

rachna, December 07, 2010 - 5:32 am UTC

Hi,
I am also running into same problem that gives me Unique Constraint Mismatch despite of having everything in sync and it works when we truncate the table.

Whats the patch # we have to install.
Tom Kyte
December 07, 2010 - 10:54 am UTC

please utilize support.

Partition exchange and index mismatch

A reader, December 13, 2012 - 10:12 am UTC

In the example below, the definition of the indexes between the two tables matches exactly. Why does it still run into the error "ORA-14098: index mismatch for tables in ALTER TABLE EXCHANGE PARTITION"?

<code>
SQL> 
SQL> SELECT * FROM v$version;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
PL/SQL Release 11.2.0.3.0 - Production
CORE 11.2.0.3.0 Production
TNS for 64-bit Windows: Version 11.2.0.3.0 - Production
NLSRTL Version 11.2.0.3.0 - Production

SQL> 
SQL> CREATE TABLE t (
  2          pkID     INTEGER NOT NULL,
  3          uniqueID INTEGER NOT NULL,
  4          theDate  DATE,
  5          theCLOB  CLOB
  6  )
  7  LOB(theCLOB) STORE AS (TABLESPACE users ENABLE STORAGE IN ROW)
  8  PARTITION BY RANGE (theDate)
  9  (
 10     PARTITION p_2009 VALUES LESS THAN (TO_DATE('2010-01-01', 'yyyy-mm-dd'))
 11        TABLESPACE TBS_2009
 12        LOB(theCLOB) STORE AS (TABLESPACE TBS_2009 ENABLE STORAGE IN ROW),
 13     PARTITION p_2010 VALUES LESS THAN (TO_DATE('2011-01-01', 'yyyy-mm-dd'))
 14        TABLESPACE TBS_2010
 15        LOB(theCLOB) STORE AS (TABLESPACE TBS_2010 ENABLE STORAGE IN ROW),
 16     PARTITION p_2011 VALUES LESS THAN (TO_DATE('2012-01-01', 'yyyy-mm-dd'))
 17        TABLESPACE TBS_2011
 18        LOB(theCLOB) STORE AS (TABLESPACE TBS_2011 ENABLE STORAGE IN ROW),
 19     PARTITION p_2012 VALUES LESS THAN (TO_DATE('2013-01-01', 'yyyy-mm-dd'))
 20        TABLESPACE TBS_2012
 21        LOB(theCLOB) STORE AS (TABLESPACE TBS_2012 ENABLE STORAGE IN ROW)
 22  );

Table created.

SQL> 
SQL> ALTER TABLE t ADD CONSTRAINT t_pk PRIMARY KEY (pkID);

Table altered.

SQL> ALTER TABLE t ADD CONSTRAINT t_u1 UNIQUE (UniqueID);

Table altered.

SQL> 
SQL> DECLARE
  2     l_data LONG := RPAD('*', 5000, '*');
  3  
  4  BEGIN
  5     INSERT INTO t (pkID, UniqueID, theDate, theCLOB) VALUES (1, 1, TO_DATE('2009-01-01', 'yyyy-mm-dd'), l_data);
  6     INSERT INTO t (pkID, UniqueID, theDate, theCLOB) VALUES (2, 2, TO_DATE('2010-01-01', 'yyyy-mm-dd'), l_data);
  7     INSERT INTO t (pkID, UniqueID, theDate, theCLOB) VALUES (3, 3, TO_DATE('2011-01-01', 'yyyy-mm-dd'), l_data);
  8     INSERT INTO t (pkID, UniqueID, theDate, theCLOB) VALUES (4, 4, TO_DATE('2012-01-01', 'yyyy-mm-dd'), l_data);
  9  END;
 10  /

PL/SQL procedure successfully completed.

SQL> 
SQL> COMMIT;

Commit complete.

SQL> 
SQL> 
SQL> CREATE TABLE p_2009 AS
  2  SELECT * FROM t WHERE 1 = 0;

Table created.

SQL> 
SQL> ALTER TABLE p_2009 ADD CONSTRAINT p_2009_pk PRIMARY KEY (pkID)
  2  USING INDEX TABLESPACE TBS_2009;

Table altered.

SQL> 
SQL> ALTER TABLE p_2009 ADD CONSTRAINT p_2009_u1 UNIQUE (UniqueID)
  2  USING INDEX TABLESPACE TBS_2009;

Table altered.

SQL> 
SQL> 
SQL> ALTER TABLE t
  2  EXCHANGE PARTITION p_2009
  3  WITH TABLE p_2009
  4  INCLUDING INDEXES
  5  WITHOUT VALIDATION
  6  UPDATE GLOBAL INDEXES;
WITH TABLE p_2009
           *
ERROR at line 3:
ORA-14098: index mismatch for tables in ALTER TABLE EXCHANGE PARTITION


</code>
Tom Kyte
December 17, 2012 - 3:56 pm UTC

the index on T(pkid) is a global index - not a local index. As is the index on T(uniqueid).

there are no indexes to exchange - you can only exchange local indexes and you have none.

More to Explore

VLDB

If you are new to partitioning, check out Connor McDonald's introduction series here.

VLDB

Documentation set on VLDB and Partitioning.