如何将具有默认值的新外键列添加到现有 table 数据
How to add new foreign key column with default value to an existing table with data
我正在努力实现这个目标:
- Table 有将近 100 条记录的 A - 添加一个新列(例如:ID
默认值为 0)
- 正在创建 ID 为 PK 的新 table B
我试过这个:
- 已将 ID 列添加到
Table A
为 null
- 将现有行的旧值更新为 0
- 已创建
Table B
ID 为 PK
- 使
Table A
中的 ID 列不为空
- 试图将 FK 约束添加到
Table A
并得到这个错误:
- ORA-02298: 无法验证未找到的父键。
我在这里错过了什么?另外,我无法删除 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
我正在努力实现这个目标:
- Table 有将近 100 条记录的 A - 添加一个新列(例如:ID 默认值为 0)
- 正在创建 ID 为 PK 的新 table B
我试过这个:
- 已将 ID 列添加到
Table A
为 null - 将现有行的旧值更新为 0
- 已创建
Table B
ID 为 PK - 使
Table A
中的 ID 列不为空
- 试图将 FK 约束添加到
Table A
并得到这个错误:
- ORA-02298: 无法验证未找到的父键。
我在这里错过了什么?另外,我无法删除 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