2

プロシージャ PROCESS_EMP はテーブル EMP を参照します。プロシージャ UPDATE_EMP は、プロシージャ PROCESS_EMP を介してテーブル EMP の行を更新します。ローカル プロシージャ PROCESS_EMP を介して EMP テーブルをクエリするリモート プロシージャ QUERY_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 は無効になり、2 回目の呼び出し時に再コンパイルされます。

私が署名について知っている限り、戻り値の型と引数のリストの組み合わせです。

1) PROCESS_EMP の署名が変更された場合、それ自体が EMP を参照しているため、EMP テーブルとは関係ありません。

2) これは正しい選択肢です。UPDATE_EMP は EMP テーブルの更新に PROCESS_EMP を使用しています。PROCESS_EMP の内部ロジックが変更された場合、 UPDATE_EMP にどのように影響しますか? UPDATE_EMP が PROCESS_EMP を使用している場合は、それを呼び出す必要があります。内部ロジックの変更は、UPDATE_EMP ではなく、PROCESS_EMP にある body に含まれます。

3) これは正しいに違いないと思いました。しかし、それは間違っています。署名の変更が PROCESS_EMP で行われた場合。戻り値の型または引数の数、またはその両方が変更された場合と同様に、呼び出し方法が影響を受けます。したがって、UPDATE_EMP が影響を受けるはずです。なぜそれは間違っているのですか?

4) と 5) の 4 点が間違っています。この「1回目」と「2回目」は出ませんでした。なぜ2回目?なぜ初めてではないのですか?正解は5点*

4

2 に答える 2

1

3 点目と 5 点目が正解です。

3番目のポイントには理由があります。

5 番目のポイントが当てはまる理由:

  • 依存モードは に設定されていTIMESTAMPます。

  • プロシージャの内部ロジックPROCESS_EMPが変更され、正常に再コンパイルされると、TIMESTAMP変更されます。ビューをクエリすることで確認できUSER_OBJECTSます。

  • に依存するすべてのプロシージャPROCESS_EMPは、すぐに無効になります。これは、ビューをクエリすることでも確認できUSER_OBJECTSます。したがって、これらのプロシージャ ( などUPDATE_EMP) は、最初に呼び出されたときに再コンパイルされます。

  • QUERY_EMPただし、 に依存するなどのリモート プロシージャは、PROCESS_EMPすぐには無効になりません。これらは、依存プロシージャが再コンパイルされた後に初めて呼び出された後に無効になります。したがってQUERY_EMP、最初に呼び出されたときに再コンパイルされません。USER_OBJECTSこれは、 を呼び出す前後にリモート データベースのビューを照会することで確認できますQUERY_EMP

  • QUERY_EMP2 回目に呼び出されると、ステータスが無効であるため、再コンパイルする必要があり、署名に変更がないため、PROCESS_EMP正常に再コンパイルおよび実行されます。

詳細については、ここここでOracle ドキュメントを参照してください。

于 2013-04-02T05:48:51.020 に答える
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 テーブルは無効になります。

False - 何もテストする必要はありません。無効化されたテーブルなどありません。(おそらくオブジェクト リレーショナル テーブルを除きますが、ここでは当てはまらないと思います。)

2) プロシージャ PROCESS_EMP の内部ロジックが変更され、正常に再コンパイルされた場合、UPDATE_EMP は無効になり、最初に呼び出されたときに再コンパイルされます。

False - 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 はまだ有効ですが、最初に呼び出されたときに失敗し、再コンパイルされません。実際、上で行ったようにパラメーターを変更しても、これは無効になりません。

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 は無効になり、2 回目の呼び出し時に再コンパイルされます。

True - QUERY_EMP は無効になり (ただし、最初の 1 回目以降は無効になります)、2 回目は正しく再コンパイルされます。クエリが実行され、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
于 2013-04-02T05:49:26.237 に答える