ORACLE:在 dbms_redefinition 后删除临时表时出错

Posted

技术标签:

【中文标题】ORACLE:在 dbms_redefinition 后删除临时表时出错【英文标题】:ORACLE: Error on Drop an interim table after dbms_redefinition 【发布时间】:2011-10-17 16:32:07 【问题描述】:

我正在开发 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】:

强制这样做很容易:

drop table INTERIM_TABLE cascade constraints;

【讨论】:

这将删除那些指向我的临时临时表的表中的行,不是吗?不是我要找的,因为这些行的外键现在也指向我重新定义的表。 没有。 CASCADE 意味着它将删除任何引用 interim_table 的约束【参考方案2】:

这是因为在运行 SYNC 和 FINISH 重新定义过程时,原始约束 STATUS 发生了变化,如下所示。您在禁用模式下从子表创建临时表的 fkey。当我们完成重定义时,我们禁用旧的 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

【讨论】:

以上是关于ORACLE:在 dbms_redefinition 后删除临时表时出错的主要内容,如果未能解决你的问题,请参考以下文章

在PostgreSQL中使用oracle_fdw访问Oracle

如何在linux下重启oracle数据库

如何在网站www.oracle.com下载oracle 10g

linux下oracle11监听配置文件在哪

怎么在linux下安装oracle数据库

如何查看oracle监听日志文件