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

How to add new foreign key column with default value to an existing table with data

我正在努力实现这个目标:

我试过这个:

并得到这个错误:

我在这里错过了什么?另外,我无法删除 Table A

中的子记录

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

You can enable or disable integrity constraints at the table level using the CREATE TABLE or ALTER TABLE statement. You can also set constraints to VALIDATE or NOVALIDATE, in any combination with ENABLE or DISABLE

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

ENABLE VALIDATE 与 ENABLE 相同。约束已检查并保证适用于所有行。

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

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

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


所以,回答你的问题

"How to add new foreign key column with default value to an existing table with data"

如果您希望约束被检查,您可以使用选项 2 ONLY,但它不是必须的 所有行都为真。这允许现有行违反约束,同时确保 所有新的或修改的行都有效。

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

起始场景 - CHILD_TABLE 有 100 行,没有 link 到 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;

现在我们要 link CHILD_TABLE 到 PARENT_TABLE,默认父级设置为 0。

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

insert into parent_table (id) values (0);

如果你不添加这个值,就像有一个默认制造商为 'HONDA' 的 VEHICLES table,但没有在 MANUFACTURERS table 中定义 '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