添加 FK 或 PK 约束是否会使某些内容无效?
Can adding FK or PK constraints invalidate something?
我有几个具有主-外键关系的表,但这些约束实际上并不存在。现在我想用 alter table
语句添加它们。
这些命令会导致任何依赖于表的对象变得无效吗?
谢谢。
这是个好问题。我们戳一下数据库看看。这是设置:
SQL> create table p23 (id number not null, col1 varchar2(10));
Table created.
SQL> create table c23 (id number not null, p_id number not null, col1 varchar2(10));
Table created.
SQL> create or replace procedure tst23
2 is
3 begin
4 insert into p23 values (1, 'ABC');
5 insert into c23 values (11, 1, 'DEF');
6 end;
7 /
Procedure created.
SQL> select status from user_objects where object_name = 'TST23';
STATUS
-------
VALID
SQL>
一切都是copacetic。现在我们将添加一些约束。
SQL> alter table p23 add constraint p23_pk primary key (id);
Table altered.
SQL> select status from user_objects where object_name = 'TST23';
STATUS
-------
VALID
SQL> alter table c23 add constraint c23_p23_fk
2 foreign key (p_id) references p23;
Table altered.
SQL> select status from user_objects where object_name = 'TST23';
STATUS
-------
VALID
SQL>
一切都还很酷。但是当我们改变 table 的结构时,就会发生这种情况......
SQL> alter table p23 add col2 date;
Table altered.
SQL> select status from user_objects where object_name = 'TST23';
STATUS
-------
INVALID
SQL>
...这正是我们想要的。
请注意,我 运行 这些测试是在 11gR2 上进行的。 Oracle 在 11g 中引入了细粒度的依赖关系跟踪,当我们 运行 DDL 对其依赖关系时,它使编程对象更加健壮。 Find out more。所以在早期版本中结果可能会有所不同。测试是值得的。
" what is the reason for the procedure to become invalid?"
添加、修改或删除列等结构更改可能会对引用对象产生影响。该过程具有未指定目标列的插入语句。所以添加一列引入了一个 ORA-00947: not enough values
错误。
但是假设我们采用了良好做法并指定了列?
SQL> create or replace procedure tst23
2 is
3 begin
4 insert into p23 (id, col1) values (1, 'ABC');
5 end;
6 /
Procedure created.
SQL> select status from user_objects where object_name = 'TST23';
STATUS
-------
VALID
SQL> alter table p23 add col4 number;
Table altered.
SQL> select status from user_objects where object_name = 'TST23';
STATUS
-------
VALID
SQL>
现在我们受到细粒度依赖项跟踪的保护。好吧,有点。我们不应该用依赖跟踪代替影响分析:
SQL> alter table p23 add col5 date not null;
Table altered.
SQL> select status from user_objects where object_name = 'TST23';
STATUS
-------
VALID
SQL>
该过程具有 VALID 状态,但当我们 运行 它时它仍然会失败,因为它不会填充新的强制列。
我有几个具有主-外键关系的表,但这些约束实际上并不存在。现在我想用 alter table
语句添加它们。
这些命令会导致任何依赖于表的对象变得无效吗?
谢谢。
这是个好问题。我们戳一下数据库看看。这是设置:
SQL> create table p23 (id number not null, col1 varchar2(10));
Table created.
SQL> create table c23 (id number not null, p_id number not null, col1 varchar2(10));
Table created.
SQL> create or replace procedure tst23
2 is
3 begin
4 insert into p23 values (1, 'ABC');
5 insert into c23 values (11, 1, 'DEF');
6 end;
7 /
Procedure created.
SQL> select status from user_objects where object_name = 'TST23';
STATUS
-------
VALID
SQL>
一切都是copacetic。现在我们将添加一些约束。
SQL> alter table p23 add constraint p23_pk primary key (id);
Table altered.
SQL> select status from user_objects where object_name = 'TST23';
STATUS
-------
VALID
SQL> alter table c23 add constraint c23_p23_fk
2 foreign key (p_id) references p23;
Table altered.
SQL> select status from user_objects where object_name = 'TST23';
STATUS
-------
VALID
SQL>
一切都还很酷。但是当我们改变 table 的结构时,就会发生这种情况......
SQL> alter table p23 add col2 date;
Table altered.
SQL> select status from user_objects where object_name = 'TST23';
STATUS
-------
INVALID
SQL>
...这正是我们想要的。
请注意,我 运行 这些测试是在 11gR2 上进行的。 Oracle 在 11g 中引入了细粒度的依赖关系跟踪,当我们 运行 DDL 对其依赖关系时,它使编程对象更加健壮。 Find out more。所以在早期版本中结果可能会有所不同。测试是值得的。
" what is the reason for the procedure to become invalid?"
添加、修改或删除列等结构更改可能会对引用对象产生影响。该过程具有未指定目标列的插入语句。所以添加一列引入了一个 ORA-00947: not enough values
错误。
但是假设我们采用了良好做法并指定了列?
SQL> create or replace procedure tst23
2 is
3 begin
4 insert into p23 (id, col1) values (1, 'ABC');
5 end;
6 /
Procedure created.
SQL> select status from user_objects where object_name = 'TST23';
STATUS
-------
VALID
SQL> alter table p23 add col4 number;
Table altered.
SQL> select status from user_objects where object_name = 'TST23';
STATUS
-------
VALID
SQL>
现在我们受到细粒度依赖项跟踪的保护。好吧,有点。我们不应该用依赖跟踪代替影响分析:
SQL> alter table p23 add col5 date not null;
Table altered.
SQL> select status from user_objects where object_name = 'TST23';
STATUS
-------
VALID
SQL>
该过程具有 VALID 状态,但当我们 运行 它时它仍然会失败,因为它不会填充新的强制列。