【问题标题】:rename or disable oracle foreign key to delete parent table重命名或禁用oracle外键删除父表
【发布时间】:2016-01-22 17:34:04
【问题描述】:

我有一个表,它的 PK 在多个表中用作 FK。由于我遇到的问题,我必须删除父表,但由于 FK,它不会让我这样做。我尝试从父表中删除 PK 和 UK,但它错误地说还有表仍在使用它们。我什至在多个表上禁用了 FK 并尝试删除表、PK 和 UK,它仍然说有表与它们相关联。

有什么方法可以在 oracle 中删除父表,然后使用完全相同的 PK 和 UK 重新创建它,而无需从多个表中删除 FK?

谢谢

【问题讨论】:

  • 您禁用了子表上的 FK?
  • 为什么要重新创建表?您可以使用alter table 命令进行任何更改。
  • 我重命名了它,因为我想确保我没有丢失数据。我应该采取更好的方法。

标签: oracle foreign-keys primary-key unique-key


【解决方案1】:

有什么方法可以在 oracle 中删除父表,然后重新创建 它具有完全相同的 PK 和 UK,而无需从中删除 FK 多个表?

是的,您使用 DBMS_REDEFINITION。作为此“修复”的一部分,您可以使用 DBMS_REDEFINITION 执行您需要执行的任何操作:重建表、添加/删除列、重新排序列、添加分区等。

不能真正做的唯一一件事就是改变主键的结构。 但是,如果你这样做,无论如何你都会丢掉所有的 FK。

这是一个简单的例子:

-- Create a parent / child relationship with data....
CREATE TABLE matt_parent
(
  id       NUMBER,
  value1   VARCHAR2 (30),
  CONSTRAINT matt_parent_pk PRIMARY KEY (id)
);

CREATE TABLE matt_child
(
  id          NUMBER,
  parent_id   NUMBER,
  value2      VARCHAR2 (30),
  CONSTRAINT matt_child_pk PRIMARY KEY (id),
  CONSTRAINT matt_child_fk1 FOREIGN KEY (parent_id) REFERENCES matt_parent (id)
);

insert into matt_parent values (1, 'XXX');

insert into matt_child values ( 100, 1, 'YYY');

COMMIT;

-- These next few SQLs use online redefinition to change the parent table (adding a column and adding partitioning)
-- First, have Oracle check whether redefinition is going to work
BEGIN
DBMS_REDEFINITION.CAN_REDEF_TABLE('apps','matt_parent',
      DBMS_REDEFINITION.CONS_USE_ROWID);
END;
/

-- Second, create our rebuilt table.  It eventually replaces our current table.
CREATE TABLE apps.matt_parent_redef
  ( 
  id       NUMBER,
  date1    DATE,
  value1   VARCHAR2 (30)
)
PARTITION BY RANGE (date1)
INTERVAL (NUMTODSINTERVAL (1,'DAY')) ( partition parent_old values less than (to_date('01-JAN-2000','DD-MON-YYYY') ));
;

-- Run this if you need to start over...
--BEGIN
--DBMS_REDEFINITION.ABORT_REDEF_TABLE (
--   uname   => 'apps',
--   orig_table => 'matt_parent',
--   int_table   => 'matt_parent_redef');
--END;


-- Third, tell Oracle to start the redefinition process.  Can take long -- copies all the data into our new table
BEGIN
DBMS_REDEFINITION.START_REDEF_TABLE('apps', 'matt_parent','matt_parent_redef',
       'id, sysdate date1, value1',
        dbms_redefinition.cons_use_rowid);
END;
/

-- Fourth, tell Oracle to copy dependent objects like PK constaints, FKs, grants, etc
DECLARE
num_errors PLS_INTEGER;
BEGIN
DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS('apps', 'matt_parent','matt_parent_redef',
   DBMS_REDEFINITION.CONS_ORIG_PARAMS, TRUE, TRUE, TRUE, TRUE, num_errors);

  DBMS_OUTPUT.PUT_LINE('Copy depenedent objects: num_errors = ' || num_errors);   
END;


-- Fifth, query to make sure there were no problems.  This should return no rows
select * from         DBA_REDEFINITION_ERRORS where base_table_name = 'MATT_PARENT';


-- Sixth, tell Oracle we're finished.  This *briefly* locks the table as the switch is accomplished.
BEGIN
DBMS_REDEFINITION.FINISH_REDEF_TABLE('apps', 'matt_parent', 'matt_parent_redef');
END;
/

-- Later, drop the redefinition version of the table.
DROP TABLE apps.matt_parent_redef CASCADE CONSTRAINTS;

-- Try to delete some parent data, just to verify our FKs are still in force.
delete from matt_parent where id = 1;

【讨论】:

  • 谢谢你,马修。问题是我没有完整的 DBA 权限。我最终禁用了所有依赖表的约束,然后使用我重命名的表并确保我有正确的主键和外键。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-23
  • 1970-01-01
  • 1970-01-01
  • 2010-10-24
  • 2013-03-14
  • 2020-01-18
  • 1970-01-01
相关资源
最近更新 更多