ORACLE: ошибка при удалении промежуточной таблицы после dbms_redefinition - PullRequest
3 голосов
/ 17 октября 2011

Я работаю над 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

без потери данных?

Заранее спасибо.

- РЕДАКТИРОВАТЬ -Подумав об этом, я решил просто удалить ограничение, чтобы разрешить удаление промежуточной таблицы.

Я изменил запрос, чтобы удалить ограничения других таблиц, которые указывают на таблицы, которые я хочуdrop, почти автоматически.

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; 

Это сработало для меня, но я должен отметить, что в моем случае этот запрос выбрасывает только одну строку (только одну зависимую таблицу), поэтому его необходимо изменить, чтобы отбрасывать многиецикл или другой метод, если вы кого-то знаете.

Было бы хорошо, если бы кто-то смог выяснить и объяснить, почему это ограничение не было удалено самим процессом (или если это нормальное поведение).

Ответы [ 2 ]

7 голосов
/ 17 октября 2011

Достаточно легко заставить это:

drop table INTERIM_TABLE cascade constraints;
2 голосов
/ 15 ноября 2013

Это потому, что исходные и новые ограничения STATUS изменяются при выполнении процедуры переопределения SYNC и FINISH, как показано ниже. Вы создаете fkeys для промежуточной таблицы из дочерних таблиц в отключенном режиме. Когда мы заканчиваем переопределение, мы отключаем старые 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...