如何将具有默认值的新外键列添加到包含数据的现有表中

时间:2018-02-10 01:13:03

标签: sql oracle oracle11g oracle10g

我试图实现这一目标:

  • 表A有近100条记录 - 添加新列(例如:ID 默认值为0)
  • 创建ID为PK
  • 的新表B.

我试过了:

  • 将ID列添加到Table A为null
  • 将现有行的旧值更新为0
  • 创建{ID为PK
  • Table B
  • Table A
  • 中将ID列设为非空
  • 尝试将FK约束添加到Table A

并收到此错误:

  • ORA-02298:无法验证未找到的父密钥。

我在这里缺少什么?此外,我无法删除Table A

中的子记录

2 个答案:

答案 0 :(得分:0)

根据这篇Ask TOM文章:Constraint ENABLE/ DISABLE

  

您可以在表级启用或禁用完整性约束   使用CREATE TABLE或ALTER TABLE语句。你也可以设置   与ENABLE任意组合的VALIDATE或NOVALIDATE约束   或者禁用

来自Tim Hall的相关文章:ORACLE-BASE

ENABLE VALIDATE与ENABLE相同。检查约束并保证对所有行保持约束。

ENABLE NOVALIDATE表示检查新行或修改行的约束,但现有数据可能违反约束。

DISABLE NOVALIDATE与DISABLE相同。未检查约束,因此数据可能违反约束。

DISABLE VALIDATE表示未检查约束,但不允许对受约束列进行任何修改。

所以,回答你的问题

  

"如何将具有默认值的新外键列添加到现有列   数据表"

如果您想要检查约束,则可以使用选项2 ,但不一定要 对于所有行都为true。这允许现有行违反约束,同时确保 所有新行或修改行都有效。

ALTER TABLE A ADD FOREIGN KEY (ID) REFERENCES B(ID)  ENABLE NOVALIDATE; 

答案 1 :(得分:0)

启动方案 - CHILD_TABLE包含100行且没有指向PARENT_TABLE的链接:

create table parent_table (id integer constraint parent_pk primary key);

create table child_table (somecolumn integer);

insert into child_table select rownum from dual connect by rownum <= 100;

现在我们要将CHILD_TABLE链接到PARENT_TABLE,并将默认父级设置为0。

为PARENT_TABLE添加一个值,以便CHILD_TABLE可以引用它:

insert into parent_table (id) values (0);

如果你不添加这个值,就像有一个VEHICLES表,默认制造商为'HONDA',但没有在MANUFACTURERS表中定义'HONDA'。外键的重点是阻止你这样做。

现在向CHILD_TABLE添加一个外键(default on null是Oracle 12.1中的新增功能,但普通default也可以,但是只有最新版本的Oracle在添加新列时才应用默认值 - 我忘了究竟是哪个版本。)

alter table child_table
add   parent_id integer
      default on null 0
      constraint child_parent_fk references parent_table ;

现在检查CHILD_TABLE中的内容:

select * from child_table;

SOMECOLUMN PARENT_ID
---------- ---------
         1         0
         2         0
         3         0
         4         0
         5         0
         6         0
         7         0
         8         0
         9         0
        10         0
        11         0

...

100 rows selected

检查新FK的状态:

select fk.constraint_name, fkc.column_name, fk.status
     , pk.table_name, fk.r_constraint_name
from   user_constraints fk
       join user_constraints pk
            on  pk.constraint_name = fk.r_constraint_name
            and pk.owner = fk.r_owner
       join user_cons_columns fkc
            on  fkc.table_name = fk.table_name
            and fkc.constraint_name = fk.constraint_name
where  fk.table_name = 'CHILD_TABLE'
and    fk.constraint_type = 'R'
and    pk.constraint_type = 'P';

CONSTRAINT_NAME    COLUMN_NAME         STATUS   TABLE_NAME          R_CONSTRAINT_NAME
------------------ ------------------- -------- ------------------- -----------------
CHILD_PARENT_FK    PARENT_ID           ENABLED  PARENT_TABLE        PARENT_PK