过程PROCESS_EMP引用表EMP。过程UPDATE_EMP通过过程PROCESS_EMP更新表EMP的行。有一个远程过程QUERY_EMP,它通过本地过程PROCESS_EMP查询EMP表。在此会话中,依赖模式设置为TIMESTAMP。哪两个陈述是真的?
1)如果修改了过程PROCESS_EMP的签名并成功重新编译,则EMP表无效。
2)如果过程PROCESS_EMP的内部逻辑被修改并成功重新编译,UPDATE_EMP将失效并在第一次调用时重新编译。
3)如果过程PROCESS_EMP的签名被修改并成功重新编译,UPDATE_EMP将失效并在第一次调用时重新编译。
4)如果过程PROCESS_EMP的内部逻辑被修改并成功重新编译,则QUERY_EMP将失效并在第一次调用时重新编译。
5)如果过程PROCESS_EMP的内部逻辑被修改并成功重新编译,则QUERY_EMP将失效,并在第二次调用时重新编译。
据我所知,签名是返回类型和参数列表的组合。
1)如果PROCESS_EMP的签名发生变化,则它与EMP表无关,因为它本身正在引用EMP。
2)这是正确的选择。 UPDATE_EMP正在使用PROCESS_EMP来更新EMP表。如果PROCESS_EMP的内部逻辑发生变化,那么它如何影响UPDATE_EMP?如果UPDATE_EMP正在使用PROCESS_EMP,那么它应该调用它。内部逻辑的更改包含在PROCESS_EMP中的主体中,而不是UPDATE_EMP中。
3)我认为这一定是正确的。但这是错误的。如果签名的更改是在PROCESS_EMP中进行的。就像返回类型或参数数量或两者都被修改一样,那么调用的方式也会受到影响。因此,UPDATE_EMP应该受到影响。为什么这是假的?
4)和5)4点不正确。我没有得到这个“第一次”和“第二次”。为什么第二次?为什么不第一次? 5分是正确的。*
答案 0 :(得分:1)
第3和第5分是对的。
第3点你有理由。
第五点成真的原因:
依赖模式设置为TIMESTAMP
。
当修改过程PROCESS_EMP
的内部逻辑并成功重新编译时,其TIMESTAMP
会发生变化。您可以通过查询USER_OBJECTS
视图来检查。
所有依赖PROCESS_EMP
的程序都会立即失效。您也可以通过查询USER_OBJECTS
视图来查看此信息。因此,当第一次调用这些过程(例如UPDATE_EMP
)时,会重新编译这些过程。
但依赖QUERY_EMP
的任何远程过程(如PROCESS_EMP
)都不会立即失效。在重新编译依赖过程后第一次调用它们时,它们将失效。因此,QUERY_EMP
在第一次调用时不会重新编译。您可以通过在调用USER_OBJECTS
之前和之后查询远程数据库上的QUERY_EMP
视图来检查这一点。
第二次调用QUERY_EMP
时,由于其状态无效,必须重新编译,因为PROCESS_EMP
的签名没有变化,它成功重新编译并执行
答案 1 :(得分:1)
3和5。
但是不要相信我的话,让我们来测试一下。
创建测试对象
--Remote dependency mode
alter session set remote_dependencies_mode = timestamp;
--Table
drop table emp purge;
create table emp(id number, name varchar2(100));
insert into emp values(1, 'asdf');
commit;
--Database link - you don't need two databases, you can link to yourself
drop database link myself;
create database link myself connect to <user> identified by <password> using '<database>';
select * from dual@myself;
--Procedures
create or replace procedure process_emp(action_type in varchar2) is
v_count number;
begin
if action_type = 'U' then
update emp set name = upper(name);
elsif action_type = 'Q' then
select count(*) into v_count from emp;
end if;
end;
/
create or replace procedure update_emp is
begin
process_emp('U');
end;
/
create or replace procedure query_emp is
begin
process_emp@myself('Q');
end;
/
--Initial object times
select object_name, last_ddl_time, status
from user_objects
where object_name in ('PROCESS_EMP', 'UPDATE_EMP', 'QUERY_EMP')
order by last_ddl_time;
PROCESS_EMP 2013-04-02 00:25:47 VALID
UPDATE_EMP 2013-04-02 00:25:48 VALID
QUERY_EMP 2013-04-02 00:25:49 VALID
<强>测试强>
1)如果修改了过程PROCESS_EMP的签名并成功重新编译,则EMP表无效。
错误 - 甚至没有在那里测试。没有失效的表格。 (除了对象关系表,但我不认为这适用于此。)
2)如果过程PROCESS_EMP的内部逻辑被修改并成功重新编译,UPDATE_EMP将失效并在第一次调用时重新编译。
错误 - UPDATE_EMP仍然有效,并且不会重新编译。 LAST_DDL_TIME不会更改。通常情况下,程序只能通过其签名来识别 - 如果这个程序没有改变,那么就不需要改变其他任何东西了。
create or replace procedure process_emp(action_type in varchar2) is
v_count number;
begin
if action_type = 'U' then
update emp set name = upper(name);
elsif action_type = 'Q' then
select count(*)+1 into v_count from emp;
end if;
end;
/
select object_name, last_ddl_time, status
from user_objects
where object_name in ('PROCESS_EMP', 'UPDATE_EMP', 'QUERY_EMP')
order by last_ddl_time;
UPDATE_EMP 2013-04-02 00:25:48 VALID
QUERY_EMP 2013-04-02 00:25:49 VALID
PROCESS_EMP 2013-04-02 00:29:20 VALID
3)如果过程PROCESS_EMP的签名被修改并成功重新编译,UPDATE_EMP将失效并在第一次调用时重新编译。
True - 更改参数可能会改变调用过程的方式。大多数更改都会导致失败,但有很多情况会发生 依赖程序将重新编译,一切都会好的。例如,如果添加默认参数:
create or replace procedure process_emp(action_type in varchar2, new_param in varchar2 default null) is
v_count number;
begin
if action_type = 'U' then
update emp set name = upper(name);
elsif action_type = 'Q' then
select count(*)+1 into v_count from emp;
end if;
end;
/
--Now the object is invalid:
select status from user_objects where object_name in ('UPDATE_EMP');
INVALID
--But no need to worry, just run it and it will automatically recompile and work correctly:
begin
update_emp;
end;
/
select status from user_objects where object_name in ('UPDATE_EMP');
VALID
4)如果过程PROCESS_EMP的内部逻辑被修改并成功重新编译,则QUERY_EMP将失效并在第一次调用时重新编译。
False - QUERY_EMP仍然是VALID,但在第一次调用时会失败,并且不会重新编译。事实上,正如我们上面所做的那样,即使更改参数也不会使此无效。
select object_name, last_ddl_time, status
from user_objects
where object_name in ('QUERY_EMP')
order by last_ddl_time;
QUERY_EMP 2013-04-02 00:25:49 VALID
begin
query_emp@myself;
end;
/
ORA-04062: timestamp of procedure "JHELLER.PROCESS_EMP" has been changed
ORA-06512: at "JHELLER.QUERY_EMP", line 3
ORA-06512: at line 2
View program sources of error stack?
5)如果过程PROCESS_EMP的内部逻辑被修改并成功重新编译,则QUERY_EMP将失效,并在第二次调用时重新编译。
True - QUERY_EMP将失效(虽然直到第一次之后),然后第二次正确重新编译。查询运行,LAST_DDL_TIME现在更新。
begin
query_emp@myself;
end;
/
select object_name, last_ddl_time, status
from user_objects
where object_name in ('QUERY_EMP')
order by last_ddl_time;
QUERY_EMP 2013-04-02 00:37:01 VALID