ORA-04062: timestamp of procedure has been changed

Problem Description
In the database I have created one procedure named a as below.

create or replace procedure a(a number) as
begin
insert into t1 values(1);
commit;
end;
/


Now after creating database link using remote database machine whenever I access this procedure "A" it executes successfully and I get value "1" in table t1. Like below in example where orastdby_m is the database link, shaik is the schema name and value 1 is the argument value though argument value is not used in the procedure.

SQL> exec shaik.a@orastdby_m(1);

PL/SQL procedure successfully completed.

Now in the source database machine I changed the procedure as below. Though you can change anything like any literal; adding space or remove space. I changed value to be inserted from 1 to 2.

create or replace procedure a(a number) as
begin
insert into t1 values(2);
commit;
end;
/


Now in the other database whenever I execute the procedure using database link it throws error ORA-04062. But subsequent execution goes ok without any error unless I change something inside the original procedure.

SQL> exec shaik.a@orastdby_m(1);
BEGIN shaik.a@orastdby_m(1); END;

*
ERROR at line 1:
ORA-04062: timestamp of procedure "SHAIK.A" has been changed
ORA-06512: at line 1


SQL> exec shaik.a@orastdby_m(1);

PL/SQL procedure successfully completed.

Problem Analysis
ORA-4062 indicates that TIMESTAMP or SIGNATURE of NAME has been changed.
When a local piece of PL/SQL references a remote package, function, or procedure, the local PL/SQL engine needs to know if the reference is still valid, or, if the remote procedure has changed.

The locally compiled PL/SQL code is dependent on the remote code. This dependency is tracked by two models either TIMESTAMPS OR SIGNATURES in oracle.

The initialization parameter REMOTE_DEPENDENCIES_MODE is responsible which method to choose. This parameter can be set to either TIMESTAMP or SIGNATURE and can be set at the instance level(By setting ALTER SYSTEM) or at the session level(By setting ALTER SESSION). This can also be set at the client side session.

Also oracle allows "runtime binding" by which client PLSQL allows to delay for the actual binding up of a reference to a SCHEMA.OBJECT.

REMOTE_DEPENDENCIES_MODE = Timestamp
If the dependency mode is set to TIMESTAMP, the local PL/SQL block can only execute the remote PL/SQL block if the timestamp on the remote procedure matches the timestamp stored in the locally compiled PL/SQL block. If the timestamps do not match, the local PL/SQL must be recompiled.

REMOTE_DEPENCIES_MODE = Signature
If the dependency mode is set to SIGNATURE, the local PL/SQL block can still execute the remote PL/SQL block if its "signature" is the same, even if the timestamp has changed.

The term "signature" basically means the interface (procedure name, parameter types or modes) is the same, even if the underlying implementation has changed.

The error "ORA-04062: timestamp of procedure has been changed" is reported if the local PL/SQL block cannot call the remote procedure, since the timestamp or signature has changed on the remote end. A local recompilation may be required to make the call.

In the case of server to server calls, the local PL/SQL block is implicitly recompiled on the next call after an ORA-4062 error. In the case of client tools to server calls, the client Form or Report usually needs to be recompiled explicitly.

Solution of the Problem
When client-side PL/SQL tools are used OR when server-side PL/SQL calls are used across database links , set REMOTE_DEPENDENCIES_MODE to SIGNATURE. This reduces the chances of the ORA-4062 errors and the need for unnecessary recompilations.
You can change in client side by,

SQL> alter session set REMOTE_DEPENDENCIES_MODE=SIGNATURE;
Session altered.

Now changing the definition of procedure "A" in the source database will not result ORA-4062 in the remote database.

Comments

Popular posts from this blog

ORA-00923: FROM keyword not found where expected

How to make partitioning in Oracle more Quickly

Copy files between Unix and Windows with rcp