2011-10-17 58 views
2

我正在使用Oracle11g,並嘗試使用dbms_redefinition重新定義表。它工作正常,但試圖放棄臨時表時會拋出ORA-02449: unique/primary keys in table referenced by foreign keys錯誤。ORACLE:在dbms_redefinition後刪除臨時表時出錯

我發現了一個查詢來尋找參考這裏在SO,

select table_name, constraint_name, status, owner 
from all_constraints 
where r_owner = 'MYSCHEMA' 
and constraint_type = 'R' 
and r_constraint_name in 
(
    select constraint_name from all_constraints 
    where constraint_type in ('P', 'U') 
    and table_name = 'INTERIM_TABLE' 
    and owner = 'MYSCHEMA' 
) 
order by table_name, constraint_name 

這給

table_name |constraint_name   |status |owner 
--------------------------------------------------------- 
anotherTable|TMP$$_anotherTable_JOB_ID0|DISABLED|MYSCHEMA 

我想,這個約束是在重新定義過程中產生的,這是確定的,但我也期望它必須通過同一過程被刪除。這是錯的嗎?我說,這個約束沒有被刪除,是正常行爲的一部分嗎?

它的安全剛落與

alter table anotherTable 
    drop constraint TMP$$_anotherTable_JOB_ID0 

的約束,而無需數據丟失?

在此先感謝。

- 編輯 - 考慮到這一點後,我決定只是刪除約束,讓臨時表被刪除。

我修改了查詢來刪除其他表的指向我想要放下的表的約束,幾乎是自動的。

DECLARE 
    my_table varchar2(100); 
    my_constraint varchar2(100); 
BEGIN 
select table_name , constraint_name into my_table,my_constraint 
from all_constraints 
where r_owner = 'MYSCHEMA' 
and constraint_type = 'R' 
and r_constraint_name in 
(
    select constraint_name from all_constraints 
    where constraint_type in ('P', 'U') 
    and table_name = 'INTERIM_TABLE' 
    and owner = 'MYSCHEMA' 
) 
order by table_name, constraint_name; 
execute immediate 'ALTER TABLE '||my_table||' DROP CONSTRAINT '|| my_constraint; 
END; 
/
DROP TABLE MYSCHEMA.INTERIM_TABLE; 

這爲我工作,但我必須指出,在我的情況該查詢拋出只有一行(只有一個依賴表),因此必須進行修改通過一個循環,或者如果你另一種方法來降很多限制認識某人。

如果有人能夠找出並解釋爲什麼該約束未被流程本身刪除(或者這是一種正常行爲),那將是一件好事。

回答

7

這是很容易給力這一點:

drop table INTERIM_TABLE cascade constraints; 
+0

這將刪除那些表中指向臨時臨時表的行,否?不是我正在尋找的,因爲這些行的外鍵現在也指向我重新定義的表。 – Keber

+1

不需要。「CASCADE」表示它將放棄引用interim_table –

+0

的任何約束條件,謝謝@a_horse_with_no_name的使用。 – Keber

2

這是因爲運行SYNC並完成重新定義過程,而原有的和新的約束狀態變化如下。您可以在禁用模式下從子表創建fkeys到臨時表。當我們完成redef時,我們禁用舊的fkeys並啓用新聞(不必驗證)。考慮:

create table t NOLOGGING 
as 
select * from all_objects; 


alter table t add constraint t_pk primary key(object_id); 

create table t1(x references t); 
create table t2(y references t); 


insert into t1 select object_id from t where rownum <= 100; 

100 rows created. 


insert into t2 select object_id from t where rownum <= 100; 
100 rows created. 



create table t_interim similar to t table. 

alter table t1 add constraint t1_new_fk foreign key(x) references t_interim disable; 

alter table t2 add constraint t2_new_fk foreign key(y) references t_interim disable; 

select constraint_name, status from user_constraints where constraint_type = 'R'; 

CONSTRAINT_NAME    STATUS 
------------------------------ -------- 
SYS_C004733     ENABLED  <<<== original constraint 
T1_NEW_FK      DISABLED 
SYS_C004734     ENABLED 
T2_NEW_FK      DISABLED 


begin 
dbms_redefinition.sync_interim_table(user, 'T', 'T_INTERIM'); 
end; 
/

PL/SQL procedure successfully completed. 

begin 
dbms_redefinition.finish_redef_table(user, 'T', 'T_INTERIM'); 
end; 
/

PL/SQL procedure successfully completed. 


select constraint_name, status from user_constraints where constraint_type = 'R'; 

CONSTRAINT_NAME    STATUS 
------------------------------ -------- 
SYS_C004733     DISABLED  <<< flip flopped the status 
T1_NEW_FK      ENABLED 
SYS_C004734     DISABLED 
T2_NEW_FK      ENABLED 

drop table t_interim cascade constraints; 

select constraint_name, status from user_constraints where 
constraint_type = 'R'; 

CONSTRAINT_NAME    STATUS 
------------------------------ -------- 
T1_NEW_FK      ENABLED 
T2_NEW_FK      ENABLED