2016-05-10 86 views
-1

在我的数据仓库中,我有一个表,其中列(ID,IDATE,NAME,GENERATION,O_ID,NODE_ID)上的唯一键TABLE_UK和列(ID,NAME,GENERATION,STRUCTURE_AREA,O_ID)上的非唯一索引PER_INDEX当我有一个非唯一索引时违反了唯一约束条件

虽然从源表装载数据我收到一个错误:

ORA-00001: unique constraint (PER_INDEX) violated

我查了独特的列,但没有重复。

为什么我在非唯一索引上得到这个唯一的约束违规错误?

另外,为了将数据加载到目标表中,我是否需要删除此索引或者是否有其他方法来执行此操作?

+1

您可以发表您的表的完整DDL,或至少描述一下'PER_INDEX'吗? – Aleksej

+0

您可以拥有唯一的由非唯一索引支持的约束。 'user_indexes'和'user_constraints'为你的表显示什么? –

回答

1

你可以有它由一个非唯一索引备份的唯一约束,如果你创建索引第一:

create table t42 (id number); 

Table T42 created. 

create index per_index on t42(id); 

Index PER_INDEX created. 

alter table t42 add constraint per_unique unique (id); 

Table T42 altered. 

select index_name, uniqueness 
from user_indexes where table_name = 'T42'; 

INDEX_NAME      UNIQUENES 
------------------------------ --------- 
PER_INDEX      NONUNIQUE 

select constraint_name, constraint_type, status, deferrable, index_name 
from user_constraints where table_name = 'T42'; 

CONSTRAINT_NAME    C STATUS DEFERRABLE  INDEX_NAME     
------------------------------ - -------- -------------- ------------------------------ 
PER_UNIQUE      U ENABLED NOT DEFERRABLE PER_INDEX      

赋予的名称似乎有可能这是第一次,然后添加一个索引稍后将限制放在顶部。

在两个步骤中做到这一点的一个原因是如果您知道现有数据不是唯一的,但您希望所有新数据都是唯一的;那么你可以创建一个非唯一索引,并与novalidate子句添加约束:

alter table t42 add constraint per_unique unique (id) novalidate; 

当一个新的行添加非唯一索引仍然可以用来快速检查是否已经有一个匹配条目,如果存在的话,约束可以抛出异常。对于该检查,索引是否是唯一的并不重要。唯一真正的区别是检查可能会获得更多的现有匹配,但是约束只是关心它是否为非零。

如果您使唯一约束可延迟,Oracle还会自动创建一个非唯一索引;具有唯一索引的异常会被抛出,立即为检查不能被推迟:

create table t42 (id number); 

Table T42 created. 

alter table t42 add constraint per_unique unique (id) deferrable; 

Table T42 altered. 

select index_name, uniqueness 
from user_indexes where table_name = 'T42'; 

INDEX_NAME      UNIQUENES 
------------------------------ --------- 
PER_UNIQUE      NONUNIQUE 

select constraint_name, constraint_type, status, deferrable, index_name 
from user_constraints where table_name = 'T42'; 

CONSTRAINT_NAME    C STATUS DEFERRABLE  INDEX_NAME     
------------------------------ - -------- -------------- ------------------------------ 
PER_UNIQUE      U ENABLED DEFERRABLE  PER_UNIQUE      

注意约束不必具有相同的名称作为索引,如果你在两个步骤创建它们 - 当您添加约束时,它将使用与约束所针对的列匹配的任何索引。当自动创建索引时,约束和索引具有相同的名称。


不能装载有违反约束,除非你将其删除的数据,但它可能有一个原因,它是不是轻率地做。你需要理解为什么约束存在,以及为什么你的数据违反了它 - 其中一个可能是错误的,但我们不能真正帮你决定。这是一个商业决策,也是一个技术问题。

+0

所以你的意思是一个非唯一索引可以作为表的唯一约束?索引'PER_INDEX'具有非唯一性,属于正常类型。 – priya77

+0

@ priya77 - 约束使用非唯一索引,是的;我不确定它在底层做了什么,但我想它可以快速使用索引来查看是否已经存在违反约束的值。为此目的,索引本身是否是唯一的并不重要。 –

+0

我的索引是为性能目的而创建的。我在源表中检查如下: 通过ID,NAME,GENERATION,STRUCTURE_AREA,O_ID从target_table组中选择count(*),ID,NAME,GENERATION,STRUCTURE_AREA,O_ID (*)> 1; 此查询返回 – priya77