3

私はOracle11gに取り組んでおり、dbms_redefinitionを使用してテーブルを再定義しようとしています。正常に動作しますが、暫定テーブルを削除しようとするとORA-02449: unique/primary keys in table referenced by foreign keysエラーがスローされます。

ここ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; 

これは私にとってはうまくいきましたが、私の場合、クエリが1つの行(1つの依存テーブルのみ)をスローすることに注意する必要があります。したがって、誰かを知っている場合は、ループまたは別のメソッドによって多くの制約を削除するように変更する必要があります。

誰かがその制約がプロセス自体によって削除されなかった理由を理解して説明できれば(またはこれが正常な動作である場合)、それは良いことです。

4

2 に答える 2

7

これを強制するのは簡単です:

drop table INTERIM_TABLE cascade constraints;
于 2011-10-17T19:42:18.367 に答える
2

これは、以下のようにSYNCおよびFINISH再定義手順を実行しているときに、元の制約と新しい制約のSTATUSが変更されるためです。無効モードで子テーブルから中間テーブルへのfkeyを作成します。再定義が完了すると、古いfkeyを無効にし、ニュースを有効にします(検証する必要はありません)。検討:

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
于 2013-11-14T21:57:27.533 に答える