我有几个具有主外键关系的表,但这些约束实际上并不存在。现在我想用alter table
语句添加它们。
这些命令会导致依赖于表的任何对象变得无效吗?
感谢。
答案 0 :(得分:2)
这是一个很好的问题。让我们捅数据库然后看看。这是设置:
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>
一切都还很酷。但是当我们改变一个桌子的结构时,就会发生这种情况......
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。因此,早期版本的结果可能会有所不同。测试是值得的。
"该程序失效的原因是什么?"
添加,修改或删除列等结构更改可能会对引用对象产生影响。该过程具有插入语句,该语句没有指定目标列。因此,添加列会引入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状态,但在运行它时仍然会失败,因为它没有填充新的强制列。