ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 运行无法解决的编译错误

运行无法解决的编译错误

原创 Linux操作系统 作者:yangtingkun 时间:2009-09-25 23:57:06 0 删除 编辑

如果运行一个过程、函数或者包,或者对视图执行查询,Oracle会检查访问的对象的状态,如果对象状态不正确,则Oracle会尝试自动编译对象。

因此绝大部分情况下,可以直接尝试执行过程,来省略编译的步骤。但是有的时候,直接运行并不起作用。

 

 

看一个简单的例子。

在本地的tnsnames.ora中加入下面的配置:

TEST112 =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 172.25.198.230)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = test112)
    )
  )

下面建立本地的数据库链,指向远端的数据库:

SQL> CREATE DATABASE LINK TEST112
  2  CONNECT TO TEST IDENTIFIED BY TEST
  3  USING 'TEST112';

数据库链接已创建。

SQL> SELECT * FROM GLOBAL_NAME@TEST112;

GLOBAL_NAME
----------------------------------------------------------------------------
TEST112

建立一个视图访问远端T表,并建立一个过程,在过程中访问视图:

SQL> CREATE VIEW V_T112
  2  AS SELECT ID FROM T@TEST112;

视图已创建。

SQL> CREATE OR REPLACE PROCEDURE P_TEST AS
  2  BEGIN
  3  UPDATE V_T112 SET ID = ID + 1;
  4  END;
  5  /

过程已创建。

SQL> EXEC P_TEST

PL/SQL 过程已成功完成。

下面修改TNSNAMES.ORA里面TEST112的配置,将配置的名称改变:

TEST1121 =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 172.25.198.230)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = test112)
    )
  )

需要注意,由于DATABASE LINK已经处于打开的状态,因此再次访问并不会报错,必须手工关闭数据库,再次访问远端对象,Oracle才会利用TNSNAMES.ORA重新解析数据库链:

SQL> EXEC P_TEST

PL/SQL 过程已成功完成。

SQL> ROLLBACK;

回退已完成。

SQL> ALTER SESSION CLOSE DATABASE LINK TEST112;

会话已更改。

SQL> EXEC P_TEST
BEGIN P_TEST; END;

*
1 行出现错误:
ORA-12154: TNS:
无法解析指定的连接标识符
ORA-06512:
"TEST.P_TEST", line 3
ORA-06512:
line 1

检查过程和视图的状态:

SQL> SELECT OBJECT_NAME, STATUS
  2  FROM USER_OBJECTS
  3  WHERE OBJECT_NAME IN ('P_TEST', 'V_T112');

OBJECT_NAME                    STATUS
------------------------------ -------
P_TEST                         VALID
V_T112                         VALID

显然Oracle并没有认为运行时的错误是由于对象失效造成的。

下面将TNSNAMES.ORA里面的配置修改回来:

TEST112 =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 172.25.198.230)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = test112)
    )
  )

重新执行过程P_TEST

SQL> EXEC P_TEST

PL/SQL 过程已成功完成。

这个现象是正常的,下面再次重复刚才的步骤,将TNSNAMES.ORA中的配置修改为TEST1121,然后运行P_TEST过程:

SQL> EXEC P_TEST

PL/SQL 过程已成功完成。

SQL> ALTER SESSION CLOSE DATABASE LINK TEST112;

会话已更改。

SQL> EXEC P_TEST
BEGIN P_TEST; END;

*
1 行出现错误:
ORA-12154: TNS:
无法解析指定的连接标识符
ORA-06512:
"TEST.P_TEST", line 3
ORA-06512:
line 1

所有的操作都和刚才一样,现在不一样的操作出现了,尝试直接访问视图:

SQL> SELECT * FROM V_T112;
SELECT * FROM V_T112
              *
1 行出现错误:
ORA-12154: TNS:
无法解析指定的连接标识符

SQL> ALTER VIEW V_T112 COMPILE;

警告: 更改的视图带有编译错误。

SQL> SELECT OBJECT_NAME, STATUS
  2  FROM USER_OBJECTS
  3  WHERE OBJECT_NAME IN ('V_T112', 'P_TEST');

OBJECT_NAME                    STATUS
------------------------------ -------
P_TEST                         INVALID
V_T112                         INVALID

由于视图的重新编译,使得视图和过程的状态都变成INVALID

下面将TNSNAMES.ORA中的配置修改正确,再次运行P_TEST过程:

SQL> EXEC P_TEST
BEGIN P_TEST; END;

      *
1 行出现错误:
ORA-06550:
1 , 7 :
PLS-00905:
对象 TEST.P_TEST 无效
ORA-06550:
1 , 7 :
PL/SQL: Statement ignored

执行仍然报错,这时手工编译P_TEST过程也是无效的:

SQL> ALTER PROCEDURE P_TEST COMPILE;

警告: 更改的过程带有编译错误。

SQL> SHOW ERR
PROCEDURE P_TEST
出现错误:

LINE/COL ERROR
-------- -----------------------------------------------------------------
3/1      PL/SQL: SQL Statement ignored
3/8      PL/SQL: ORA-04063: view "TEST.V_T112"
有错误

无论是直接运行过程,还是手工编译过程,都无法解决视图的问题,这时只能通过手工编译错误的视图才能解决这个错误。

SQL> ALTER VIEW V_T112 COMPILE;

视图已变更。

SQL> ALTER PROCEDURE P_TEST COMPILE;

过程已更改。

SQL> EXEC P_TEST

PL/SQL 过程已成功完成。

 

 

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

请登录后发表评论 登录
全部评论
暂无介绍

注册时间:2007-12-29

  • 博文量
    1955
  • 访问量
    10422932