一次ORA-942错误的跟踪(五)

今天碰到一个很有意思的错误,通过JAVA程序连接数据库,运行程序时报错,错误信息就是ORA-00942: table or view does not exist

这篇描述重现问题过程。

一次ORA-942错误的跟踪(一):http://yangtingkun.itpub.net/post/468/480559

一次ORA-942错误的跟踪(二):http://yangtingkun.itpub.net/post/468/480671

一次ORA-942错误的跟踪(三):http://yangtingkun.itpub.net/post/468/480744

一次ORA-942错误的跟踪(四):http://yangtingkun.itpub.net/post/468/480825

 

 

在上面一篇文章中,已经最终定位了问题产生的原因,并找到了Oracle对应的BUG描述,验证了解决这个问题的方法。可以说这个问题已经被解决了。

不过对于真正理解这个问题而言,还差一个关键的步骤,就是重现问题。

通过人为的构造一个最简单的环境来再现问题,对于将问题提交给Oracle的支持部门或向其他人提问等情况是十分有帮助的。如果看不到环境,没有办法动手进行测试,是很难确定问题的原因的。因此能够在本地重现问题,被定位并解决的可能性要大得多。

而且重现问题本身也是一个解决问题的一部分。通过构造一个最简单的环境在重现问题,可以将问题相关的因素搞清楚。一般来说,一个问题可能和数据库中的很多因素有关。通过重现这个问题,可以最终确定是哪些因素导致了错误的发生。

举一个例子:在Oracle9204上碰到了一个SQL问题,FIRST_ROWS优化模式下,通过数据库链访问远端表,且SQL包括IN子查询语句时,优化器可能给出错误的执行计划,从而导致结果集出现重复记录。对于这个错误,可能与Oracle的版本、所在平台、分布式查询、IN查询子句、CBO优化模式等多个因素有关。确定导致问题的原因本身就比较困难。那么可以通过重现问题的方式来确定导致问题的原因。具体方法是每次测试的时候减少一个可能影响问题的因素,然后检查问题是否可以重现。比如换一个10g的数据库环境执行相同的SQL,如果仍然出现问题,说明这个问题和多个数据库版本都有关系,如果不出现问题,说明9204版本是导致问题出现的一个因素。然后9204版本中,访问本地表,检查问题是否可以重现,如果能够重现,说明问题与是否访问远端对象无关,反之说明访问远端对象也是影响问题的因素之一。通过不断的测试,最终找到导致并引发问题的所有原因。在构造最简单的重现错误的环境的过程中,已经将问题导致的原因确定清楚了。

对于当前这种情况,错误的原因已经清楚了,解决错误的方法也找到了。那么重现问题是否还有意义呢?答案仍然是有意义。因为重现问题的过程,可以验证你对问题的理解是否正确。如果你的理解是正确的,那么就可以很轻松的在线这个错误。如果你无法在线这个错误,那么肯定是你的理解不正确,后者说你还漏掉了一些很关键的因素。

下面在Oracle 10.2.0.3 for Solaris平台下模拟这个错误:

SQL> SELECT * FROM V$VERSION;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bi
PL/SQL Release 10.2.0.3.0 - Production
CORE    10.2.0.3.0      Production
TNS for Solaris: Version 10.2.0.3.0 - Production
NLSRTL Version 10.2.0.3.0 - Production

SQL> CREATE USER A1 IDENTIFIED BY A1 DEFAULT TABLESPACE USERS;

用户已创建。

SQL> CREATE USER A2 IDENTIFIED BY A2 DEFAULT TABLESPACE USERS;

用户已创建。

SQL> CREATE USER B1 IDENTIFIED BY B1 DEFAULT TABLESPACE USERS;

用户已创建。

SQL> CREATE USER B2 IDENTIFIED BY B2 DEFAULT TABLESPACE USERS;

用户已创建。

SQL> GRANT CONNECT, RESOURCE TO A1;

授权成功。

SQL> GRANT CONNECT, RESOURCE TO B1;

授权成功。

SQL> GRANT CREATE SESSION, CREATE SYNONYM TO A2;

授权成功。

SQL> GRANT CREATE SESSION, CREATE SYNONYM TO B2;

授权成功。

SQL> CONN A1/A1
已连接。
SQL> CREATE TABLE T (ID NUMBER);

表已创建。

SQL> GRANT SELECT ON T TO A2;

授权成功。

SQL> CONN A2/A2
已连接。
SQL> CREATE SYNONYM T FOR A1.T;

同义词已创建。

SQL> SELECT * FROM T;

未选定行

SQL> CONN B1/B1
已连接。
SQL> CREATE TABLE T (ID NUMBER); 

表已创建。

SQL> GRANT SELECT ON T TO B2;

授权成功。

SQL> CONN B2/B2
已连接。
SQL> CREATE SYNONYM T FOR A2.T;

同义词已创建。

SQL> SELECT * FROM T;
SELECT * FROM T
              *
1 行出现错误:
ORA-00942:
表或视图不存在


SQL> DROP SYNONYM T;

同义词已删除。

SQL> CREATE SYNONYM T FOR B1.T;

同义词已创建。

SQL> SELECT * FROM T;
SELECT * FROM T
              *
1 行出现错误:
ORA-00942:
表或视图不存在


SQL> SELECT * FROM t;

未选定行

SQL> SELECT * FROM T A;

未选定行

简单描述一下重现的步骤,首先建立了4个用户,A1A2B1B2。其中A1B1中建立了表,并把查询权限分别授予A2B2

A2中建立指向A1的同义词,并进行访问。

B2中建立指向A1A2的同义词,访问时会报错,这是由于B2没有访问A1对象的权限。

B2的同义词删除,并指向B1的对象。这时B2的同义词指向了B1的对象,且B2拥有权限这个对象的权限,但是Oraclebug导致了共享池中错误的SQL解析的存在,导致匹配这个SQL的访问报错。如果改变表名的大小写,或者添加别名,就不会报错。

现在成功了再现了这个错误,至此错误的解决过程全部结束。

 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/4227/viewspace-573387/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/4227/viewspace-573387/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值