在Oracle中截断表获取错误

时间:2011-01-27 02:35:39

标签: sql oracle plsql

我遇到的问题是当我在Oracle中运行以下命令时,遇到错误。

Truncate table mytable;

错误:

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

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

9 个答案:

答案 0 :(得分:34)

您必须将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

即可

答案 1 :(得分:8)

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

根据Oracle docs

  

您无法截断父表   已启用的外键约束。   您必须先禁用约束   截断表格。

syntax for disabling a foreign key是:

  

ALTER TABLE table_name disable   CONSTRAINT constraint_name;

答案 2 :(得分:8)

此页面提供了一个非常好的解决方案......

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

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

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

    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');
    

答案 3 :(得分: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;

- 运行truncate

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;

答案 4 :(得分:1)

Oracle 12c introduced a feature截断一个表,该表是具有ON DELETE规则的参照完整性约束的父级。

而不是truncate table tablename;使用:

TRUNCATE TABLE tablename CASCADE;

来自Oracle truncate table文档:

  

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

答案 5 :(得分:0)

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

  • 使用所有列创建mytable_new但没有约束(或禁用创建约束);
  • 将您需要的所有数据从mytable复制到mytable_new
  • mytable_new上启用约束,以确保一切正常。
  • 更改引用mytable引用mytable_new的所有约束,并查看一切正常。
  • drop table mytable
  • alter table mytable_new rename to mytable

这比删除一百万条有很多慢速限制的记录要快得多。

答案 6 :(得分: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;
/

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

希望它有所帮助。

欢呼..

答案 7 :(得分:0)

TRUNCATE TABLE TEST2 DROP ALL STORAGE;

此声明实际上在.table

上应用外键约束时有效

答案 8 :(得分:-1)

如错误消息所述,您不能截断启用的外键引用的表。如果您确实想使用truncate DDL命令,请先禁用外键约束,运行truncate命令,然后再将其启用。

参考:Difference between TRUNCATE, DELETE and DROP commands