运行无法解决的编译错误[转帖]_MySQL, Oracle及数据库讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  MySQL, Oracle及数据库讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 3991 | 回复: 0   主题: 运行无法解决的编译错误[转帖]        下一篇 
wayne
注册用户
等级:中校
经验:1690
发帖:221
精华:0
注册:2011-7-21
状态:离线
发送短消息息给wayne 加好友    发送短消息息给wayne 发消息
发表于: IP:您无权察看 2011-8-25 18:20:01 | [全部帖] [楼主帖] 楼主

如果运行一个过程、函数或者包,或者对视图执行查询,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 过程已成功完成。




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论