2011-01-27 94 views
19

我得到的问题是当我在Oracle中运行以下命令时,遇到错误。Oracle中的截断表获取错误

Truncate table mytable; 

错误:

ORA-02266: unique/primary keys in table referenced by enabled foreign keys 

我发现,这MYTABLE与其他表的关系。这就是为什么截断命令不能继续。如何使用Truncate命令从SQL脚本中删除myTable中的数据?

回答

27

您必须将TRUNCATE语句交换为DELETE语句,速度较慢且已记录,但这是在约束到位时执行的方式。

DELETE mytablename; 

无论是或者你可以找到引用有问题的表的外键,并暂时禁用它们。

select 'ALTER TABLE '||TABLE_NAME||' DISABLE CONSTRAINT '||CONSTRAINT_NAME||';' 
from user_constraints 
where R_CONSTRAINT_NAME='<pk-of-table>'; 

pk-of-table是表中的主键的名称被截断

运行上述查询的输出。当完成后,请记住再次启用它们,只需将DISABLE CONSTRAINT更改为ENABLE CONSTRAINT

+0

我不能使用Delete语句,因为这个表有超过一百万条记录,如果我使用delete,它会变慢。 – ppshein 2011-01-27 02:41:13

+0

如果它有一百万条记录,我假设你在截断之前删除所有链接到它的子记录? – RichardTheKiwi 2011-01-27 02:45:53

+0

我会遵循cyberkiwi关于禁用约束的选项。这样你就不会放弃限制。看看这篇文章,更详细地了解truncate的行为http://psoug.org/reference/truncate.html – 2011-01-27 02:48:18

8

错误消息告诉您还有其他表引用了您的表的外键约束。

按照Oracle docs

您不能截断父表的启用外键约束 。 您必须禁用 截断表之前的约束。

syntax for disabling a foreign key是:

ALTER TABLE TABLE_NAME禁用 约束constraint_name命令;

0

的典型方法有许多约束来删除许多行如下:

  • 创建mytable_new与所有列,但没有约束(或创建约束禁用);
  • 将您需要的任何数据从mytable复制到mytable_new
  • 启用对mytable_new的约束来查看一切正常。
  • 改变任何参考mytable引用mytable_new的约束,看看一切正常。
  • drop table mytable
  • alter table mytable_new rename to mytable

这比删除一百万条缓慢约束的记录要快得多。

8

这个页面提供了一个很好的解决方案......

ORA-02266: unique/primary keys in table referenced by enabled foreign keys

我在这里从它复制的解决方案:

  • 查找引用启用外键约束并禁用它们。
  • 从表中截断/删除。
  • 使用任何文本编辑器..只需更改禁用以启用从查询获得的输出,然后运行它。

    select 'alter table '||a.owner||'.'||a.table_name||' disable constraint '||a.constraint_name||';' 
    from all_constraints a, all_constraints b 
    where a.constraint_type = 'R' and a.status='ENABLED' 
    and a.r_constraint_name = b.constraint_name 
    and a.r_owner = b.owner 
    and b.table_name = upper('YOUR_TABLE'); 
    
1

甲骨文12C introduced a feature截断表,其是具有ON DELETE规则参照完整性约束的父。

而不是truncate table tablename;使用:

TRUNCATE TABLE tablename CASCADE; 

从甲骨文truncate table文档:

如果指定CASCADE,那么Oracle数据库截断ON DELETE CASCADE引用约束启用引用表与所有子表。这是一个递归操作,它将使用指定的选项截断所有子表,granchild表等。

0

我有类似的问题,我通过以下脚本对它进行了整理。

begin 
for i in (select constraint_name, table_name from user_constraints a where a.owner='OWNER' and a.table_name not in 
(select b.table_name from user_constraints b where b.table_name like '%BIN%') 
    and a.constraint_type not in 'P') 
LOOP 
    execute immediate 'alter table '||i.table_name||' disable constraint '||i.constraint_name||''; 
end loop; 
end; 
/

truncate table TABLE_1; 
truncate table TABLE_2; 


begin 
for i in (select constraint_name, table_name from user_constraints a where a.owner='OWNER' and a.table_name not in 
(select b.table_name from user_constraints b where b.table_name like '%BIN%') 
    and a.constraint_type not in 'P') 
LOOP 
    execute immediate 'alter table '||i.table_name||' enable constraint '||i.constraint_name||''; 
end loop; 
end; 
/

该脚本将首先禁用所有约束。截断表中的数据,然后启用约束。

希望它有帮助。

欢呼声..

0
TRUNCATE TABLE TEST2 DROP ALL STORAGE; 

这种说法实际工作时,有应用上。表

2

问题的外键约束:

Error “ORA-02266: unique/primary keys in table referenced by enabled foreign keys” when trying to truncate a table. 

错误消息:

SQL> truncate table TABLE_NAME; 

truncate table TABLE_NAME 
      * 
ERROR at line 1: 
ORA-02266: unique/primary keys in table referenced by enabled foreign keys 

解决方案: - 查找引用的外键约束。

SQL> select 'alter table '||a.owner||'.'||a.table_name||' disable constraint '||a.constraint_name||';' 
    2 from all_constraints a, all_constraints b 
    3 where a.constraint_type = 'R' 
    4 and a.r_constraint_name = b.constraint_name 
    5 and a.r_owner = b.owner 
    6 and b.table_name = 'TABLE_NAME'; 

    'ALTER TABLE'||A.OWNER||'.'||A.TABLE_NAME||'DISABLE CONSTRAINT'||A.CONSTRAINT_NAME||';' 
    --------------------------------------------------------------------------------------------------------- 
    alter table SCHEMA_NAME.TABLE_NAME_ATTACHMENT disable constraint CONSTRAINT_NAME;  
alter table SCHEMA_NAME.TABLE_NAME_LOCATION disable constraint CONSTRAINT_NAME; 

- 禁用它们

alter table SCHEMA_NAME.TABLE_NAME_ATTACHMENT disable constraint CONSTRAINT_NAME; 
alter table SCHEMA_NAME.TABLE_NAME_LOCATION disable constraint CONSTRAINT_NAME; 

- 运行截断

SQL> truncate table TABLE_NAME; 

Table truncated. 

- 启用外键回

SQL> select 'alter table '||a.owner||'.'||a.table_name||' enable constraint '||a.constraint_name||';' 
    2 from all_constraints a, all_constraints b 
    3 where a.constraint_type = 'R' 
    4 and a.r_constraint_name = b.constraint_name 
    5 and a.r_owner = b.owner 
    6 and b.table_name = 'TABLE_NAME'; 

'ALTER TABLE'||A.OWNER||'.'||A.TABLE_NAME||'ENABLE CONSTRAINT'||A.CONSTRAINT_NAME||';' 
-------------------------------------------------------------------------------- 

alter table SCHEMA_NAME.TABLE_NAME_ATTACHMENT enable constraint CONSTRAINT_NAME; 
alter table SCHEMA_NAME.TABLE_NAME_LOCATION enable constraint CONSTRAINT_NAME; 

- 允许他们

alter table SCHEMA_NAME.TABLE_NAME_ATTACHMENT enable constraint CONSTRAINT_NAME; 
alter table SCHEMA_NAME.TABLE_NAME_LOCATION enable constraint CONSTRAINT_NAME;