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;