【问题标题】:Why dropping a primary key is not dropping its unique index?为什么删除主键不会删除其唯一索引?
【发布时间】:2015-10-28 16:47:48
【问题描述】:
  1. 我有一个表,其中Col1Col2 作为复合主键pk_composit_key 和一个为约束自动创建的唯一索引。
  2. 然后我更改了表格以添加新列Col3
  3. 我放弃了pk_composit_key 约束:

    ALTER TABLE table_name DROP CONSTRAINT pk_composit_key;

  4. 现在,当我尝试插入记录时,我得到了ORA-00001: unique constraint pk_composit_key violated

    • 为什么会出现该错误?
    • 删除键后,为什么没有自动删除唯一索引?

【问题讨论】:

  • 您插入的记录是否违反了新的三值复合键,无论如何都会有同名的索引?你不能按你说的去做。如果索引是由第一个约束自动创建的,它将被删除。如果它是在约束之前手动创建的,那么它会在删除之后保留,但第二个约束的创建将失败,因为现有索引现在与约束列不匹配。
  • @AlexPoole 当我们删除约束时,索引仍然存在。然后当我们尝试插入新记录时,它会说唯一索引违规。我稍微更新了问题
  • 当您尝试打破约束时,您会遇到唯一索引冲突,这是正常的。您现在是说在尝试重新创建主键之前遇到该错误吗?还是重建后?你是如何检查它在最初的下降后仍然存在的?目前我不确定你是否只是误解了你得到的错误,当你插入实际上有重复 col1、col2、col3 值的数据时;或者如果您没有重新创建约束,无论您是第一次手动创建索引。
  • @AlexPoole 我在插入时在第 4 步出错。尚未创建新的约束。我可以在 user_indexes 中列出该索引名称。
  • 能否创建一个测试用例,包含所有创建表、约束等语句,重现问题?这样,我们可以尝试为自己重复相同的步骤,这将使我们能够为您提供更好的帮助。

标签: oracle unique-constraint composite-primary-key


【解决方案1】:

您提到了导出和导入架构,如果这种情况发生在表现出这种行为的环境中,它将解释您所看到的;至少如果您使用旧版 imp 而不是数据泵 impdp

The original import documentation 表示订单对象已导入:

表对象在从导出转储文件中读取时被导入。转储文件包含以下顺序的对象:

  • 类型定义
  • 表定义
  • 表格数据
  • 表索引
  • 完整性约束、视图、过程和触发器
  • 位图、基于函数和域索引

所以唯一索引会被导入,然后约束就会被创建。

When you drop a primary key constraint:

  • 如果主键是使用现有索引创建的,则不会删除该索引。
  • 如果主键是使用系统生成的索引创建的,则会删除该索引。

由于导入顺序,约束使用现有索引,所以第一个项目符号适用;并且在删除约束时保留索引。

您可以使用drop index clause 删除索引,即使它不是自动创建的:

ALTER TABLE table_name DROP CONSTRAINT pk_composit_key DROP INDEX;

另请参阅 My Oracle Support 说明 370633.1;和 1455492.1 表明数据泵导入也会发生类似的行为。我不知道有什么方法可以检查索引是否与此级别的约束相关联;手动或自动创建索引时,dba_constraintsdba_indexes 视图没有区别。包含drop index 会使其保持一致。

【讨论】:

  • 发现这个“ 由于您进行了导出和导入,导入的工作方式是单独创建索引,然后单独添加主键约束。因为在导入的情况下,这两件事是分开发生的,删除主键现在不会删除索引。” community.oracle.com/message/1223619
【解决方案2】:

这取决于如何创建唯一索引...以下是各种方式和行为

1) 首先创建唯一索引(在要定义主键的列上),然后添加主键约束。在这种情况下,您添加主键的 DDL 将利用现有的唯一索引。因此,当您删除主键时,它不会删除索引,而只会删除主键。 ==> 我猜这是你的情况...

2) 在创建表时定义主键或者当你添加主键时,当没有为要定义主键的列的现有唯一索引时,系统将创建一个唯一索引并将其用作主键。因此,在这种情况下,当您删除主键时,唯一索引也将被删除。

【讨论】:

  • 除了问题说明索引是自动创建的。当然,这可能不正确——事实上,对所发生事情的描述可能不太正确。不过,对于独立的唯一索引来说,这将是一个奇怪的名称。 (另外,doc link 的行为)。
  • 是的@AlexPoole,我的假设是唯一约束是在创建约束时自动创建的。我们可以确认它是手动创建的还是自动创建的?
  • 如果约束或索引是由系统自动创建的,那么它将有不同的命名约定(SYS%),同样会在错误消息中显示它不会是错误消息中的pk_composit_key。
  • @narendra,这是在生产中创建表的方式 CREATE TABLE DATA_SOURCE ( COL1 VARCHAR2(4), COL2 VARCHAR2(4), COL3 VARCHAR2(200), DATA1 VARCHAR2(30), DATA2 VARCHAR2( 30)约束PK_COMPOSIT_KEY主键(COL1,COL2));
  • @narendra - 除非它没有被命名;如果您命名约束,则索引名称将匹配。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-06
  • 2020-10-01
  • 1970-01-01
  • 2019-01-13
  • 2019-01-12
相关资源
最近更新 更多