Error: ORA-04062: timestamp of procedure has been changed

环境:rhel5.3 oracle 11.2.0.1.0

现象:

数据库1(db1)上过程p1通过dblink调用数据库2(db2)上的过程p2

当db2上p2中的内容改变后,重新编译后,再重新编译db1上的p1是没问题的,但运行p1时就回报错:  --注意是运行时报错

Error: ORA-04062: timestamp of procedure   has been changed

经过查询一些资料,得知是REMOTE_DEPENDENCIES_MODE = { TIMESTAMP | SIGNATURE } 导致的


11.2oracle文档解释:

REMOTE_DEPENDENCIES_MODEProperty Description 
Parameter type String 
Syntax REMOTE_DEPENDENCIES_MODE = { TIMESTAMP | SIGNATURE } 
Default value TIMESTAMP 
Modifiable ALTER SESSION, ALTER SYSTEM 

REMOTE_DEPENDENCIES_MODE specifies how Oracle should handle dependencies upon remote PL/SQL stored procedures.

Values:

•TIMESTAMP
The client running the procedure compares the timestamp recorded on the server-side procedure with the current timestamp of the local procedure and executes the procedure only if the timestamps match.

•SIGNATURE
Oracle allows the procedure to execute as long as the signatures are considered safe. This setting allows client PL/SQL applications to be run without recompilation.


以上的timestamp 是等价于dba_objests里面的timestamp 列值,测试:

SQL> create procedure p
as
begin
  null;
end;
/
Procedure created.
--注意:11.2.0.1.0的环境,创建完过程后,再次使用pl/sql developer查看时oracle直接给你增加了 or replace 变成:
create or replace procedure p as
begin
null;
end;

SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';
Session altered.

SQL>  select last_ddl_time, timestamp from user_objects where object_name = 'P';

LAST_DDL_TIME    TIMESTAMP
------------------- -------------------
2013-07-28 14:12:12 2013-07-28:14:12:12

SQL> grant execute on P to public;
Grant succeeded.

SQL>  select last_ddl_time, timestamp from user_objects where object_name = 'P';

LAST_DDL_TIME    TIMESTAMP
------------------- -------------------
2013-07-28 14:28:45 2013-07-28:14:12:12

SQL> alter procedure P compile;
Procedure altered.

SQL> select last_ddl_time, timestamp from user_objects where object_name = 'P';

LAST_DDL_TIME    TIMESTAMP
------------------- -------------------
2013-07-28 14:33:48 2013-07-28:14:12:12

--这里使用pl/sql developer工具编译后,下面timestamp马上发生了变化,所以可以得出pl/sql developer工具编译时和sqlplus原理不一样

SQL> select last_ddl_time, timestamp from user_objects where object_name = 'P';

LAST_DDL_TIME    TIMESTAMP
------------------- -------------------
2013-07-28 14:35:05 2013-07-28:14:35:05

SQL> alter procedure P compile;
Procedure altered.

SQL> select last_ddl_time, timestamp from user_objects where object_name = 'P';


LAST_DDL_TIME    TIMESTAMP
------------------- -------------------
2013-07-28 14:36:26 2013-07-28:14:35:50

SQL> alter procedure P compile;
Procedure altered.

SQL> select last_ddl_time, timestamp from user_objects where object_name = 'P';

LAST_DDL_TIME    TIMESTAMP
------------------- -------------------
2013-07-28 14:36:41 2013-07-28:14:35:50


以上测试说明:

all_objects中的last_ddl_time包括了grant,同时也包括了revoke ;create procedure会直接变成 create or replace procedure ,使用pl/sql developer

会改变timestamp 值,但sqlplus 不会;如果过程的内容改变了,不管使用哪个工具timestamp都会改变


所以解决以上错误只有以下2种方式:

1:alter procedure xxx   compile;   --运行过程前提前把含有dblink过程编译一下

        2:alter session set remote_dependencies_mode=signature;


在p1的过程中在引用dblink过程之前增加:

EXECUTE IMMEDIATE 'alter session set remote_dependencies_mode=signature';


即可解决问题。


signature 基本意味着程序接口(过程名,参数类型或者模式),关于具体什么情况会改变signature,现在还不清楚,有资料说:

改变in/out 参数,或者表结构会导致signature改变!!,现在还没遇见,后续如遇signature报错问题会继续一一补充在下面!!



<think>嗯,用户遇到了在Linux环境下Oracle数据库的ORA-01031权限不足的问题,需要解决。首先,我得回忆一下ORA-01031错误的常见原因。根据提供的引用,比如引用[1]提到在存储过程执行时出现权限不足,可能涉及权限继承的问题。引用[2]和[3]讨论了Windows下的解决方法,但用户需要的是Linux环境下的方案,不过原理应该是类似的。 首先,用户可能没有足够的系统权限。比如,以SYSDBA或SYSOPER身份登录时,需要操作系统认证或密码文件认证。在Linux下,通常需要用户属于dba组,或者使用正确的认证方式。可能用户没有将当前用户添加到dba组中,导致权限不足。这时候需要检查/etc/group文件,确认用户所属的组是否包含dba。 其次,权限问题可能出现在对象权限上。比如用户尝试访问的表、存储过程等,没有授予相应的权限。需要检查用户是否有EXECUTE权限,或者是否有通过角色获得的权限。因为有时候权限是通过角色授予的,但在存储过程中可能不会继承角色权限,这时候需要直接授予用户权限。 另外,密码文件的问题也可能导致错误。如果使用密码文件认证,需要确认密码文件存在,并且用户有SYSDBA权限。可以使用orapwd工具重新生成密码文件,并确保初始化参数remote_login_passwordfile设置为EXCLUSIVE或SHARED。 还有,环境变量是否正确设置?比如ORACLE_SID和ORACLE_HOME是否正确配置。如果这些变量没有正确设置,可能导致连接到错误的实例或没有权限访问相关文件。 可能还需要检查sqlnet.ora文件中的SQLNET.AUTHENTICATION_SERVICES参数是否包含NTS(在Linux下可能不适用,但需要确认认证方式是否正确)。不过Linux通常使用基于操作系统的认证,所以需要确保用户属于正确的OS组。 步骤方面,首先应该确认用户登录的方式是否正确,比如是否使用了正确的连接字符串,是否以SYSDBA身份登录。然后检查用户权限,包括系统权限和对象权限。接着查看密码文件和组配置,最后考虑重新授权或重启实例。 可能需要指导用户如何检查这些配置,比如通过SQL查询查看用户的权限,检查用户所属的组,检查密码文件是否存在等。同时,根据引用[3]中的方法,虽然是在Windows下,但修改sqlnet.ora和添加用户到dba组的步骤在Linux下也是类似的,需要相应调整。</think>### Linux环境下Oracle数据库ORA-01031权限不足解决方案 #### 一、问题定位 ORA-01031错误表示当前用户缺乏执行操作所需的系统或对象权限[^1]。在Linux环境中需重点关注以下方向: 1. 操作系统认证配置 2. 用户权限继承方式 3. 密码文件有效性 4. 角色权限激活状态 #### 二、分步解决方案 1. **操作系统认证检查** ```bash # 检查用户是否在dba组 grep 'dba' /etc/group # 添加用户到dba组(需root权限) usermod -aG dba $ORACLE_USER ``` 系统认证要求用户必须属于dba组才能使用`/ as sysdba`登录[^3] 2. **权限验证** ```sql -- 检查用户权限 SELECT * FROM USER_SYS_PRIVS; -- 验证角色权限是否激活 SELECT * FROM SESSION_ROLES; ``` 注意:存储过程执行时不会继承角色权限,需直接授予权限 3. **密码文件配置** ```sql -- 检查密码文件状态 SHOW PARAMETER passwordfile; -- 重建密码文件(需停止实例) orapwd file=$ORACLE_HOME/dbs/orapw$ORACLE_SID password=新密码 entries=10 ``` 4. **权限修复示例** ```sql -- 授予系统权限 GRANT CREATE SESSION, CREATE TABLE TO 用户名; -- 授予对象权限 GRANT EXECUTE ON 存储过程名 TO 用户名; ``` #### 三、配置验证流程 1. 重新登录测试 ```bash sqlplus / as sysdba ``` 2. 检查登录身份 ```sql SHOW USER ``` 3. 验证关键权限 ```sql SELECT * FROM V$PWFILE_USERS; ``` #### 四、特殊场景处理 **案例:执行存储过程报错ORA-01031** 1. 检查存储过程属主 2. 授予直接权限(非通过角色) ```sql GRANT EXECUTE ON 存储过程 TO 用户 WITH GRANT OPTION; ``` 3. 重新编译对象 ```sql ALTER PROCEDURE 存储过程名 COMPILE; ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值