【好文共分享】关于ora-04065和ora-04068的原理解释
转自:http://tech.it168.com/oldarticle/2006-05-26/200605252326345.shtml
今天在运行一个过程是报了一个ORA-4068错误。虽然问题很简单,而且也很容易解决,但是要真正理解的错误产生的原因,还需要对概念理解的比较清晰。
下面做一个简单的例子重现错误:
SQL> CREATE TABLE T AS SELECT * FROM TAB;
表已创建。
SQL> CREATE OR REPLACE PROCEDURE P_RECREATE AS
2 BEGIN
3 EXECUTE IMMEDIATE 'DROP TABLE T';
4 EXECUTE IMMEDIATE 'CREATE TABLE T AS SELECT * FROM TAB';
5 END;
6 /
过程已创建。
SQL> CREATE OR REPLACE PROCEDURE P_INSERT_T AS
2 BEGIN
3 INSERT INTO T SELECT * FROM T;
4 END;
5 /
过程已创建。
SQL> BEGIN
2 P_RECREATE;
3 P_INSERT_T;
4 END;
5 /
BEGIN
*第 1 行出现错误:
ORA-04068: 已丢弃程序包 的当前状态
ORA-04065: 未执行, 已更改或删除 stored procedure "YANGTK.P_INSERT_T"
ORA-06508: PL/SQL: 无法找到正在调用 : "YANGTK.P_INSERT_T" 的程序单元
ORA-06512: 在 line 3
如果单独执行两个过程,则不会报错:
SQL> EXEC P_RECREATE PL/SQL 过程已成功完成。 SQL> EXEC P_INSERT_T PL/SQL 过程已成功完成。
看到ORA-04068错误,我首先想到的是由于在P_RECREATE过程中,对表进行了删除重建工作,导致和这个表相关的存储过程变为INVALID。
于是,我尝试在调用过程之前重编译P_INSERT_T过程:
SQL> BEGIN
2 P_RECREATE;
3 EXECUTE IMMEDIATE 'ALTER PROCEDURE P_INSERT_T COMPILE';
4 P_INSERT_T;
5 END;
6 /
BEGIN
*第 1 行出现错误:
ORA-04068: 已丢弃程序包 的当前状态
ORA-04065: 未执行, 已更改或删除 stored procedure "YANGTK.P_INSERT_T"
ORA-06508: PL/SQL: 无法找到正在调用 : "YANGTK.P_INSERT_T" 的程序单元
ORA-06512: 在 line 4
但是发现,错误依旧。
SQL> BEGIN
2 P_RECREATE;
3 EXECUTE IMMEDIATE 'BEGIN P_INSERT_T; END;';
4 END;
5 /
PL/SQL 过程已成功完成。
但如果使用动态SQL的方式调用P_INSERT_T过程,则不会报错。
问题已经基本上清楚了,但是要想说明白,还需要从头说起。
存储过程在编译时,自动检查语法错误、权限以及所有对象依赖性等。等到执行的时候,Oracle不会再进行类似的检查,而是直接运行过程,这也是存储过程拥有较高效率的一个原因。
当存储过程依赖的对象发生变化了,Oralce会自动将存储过程的状态置为INVALID,而存储过程的状态如果为INVALID,则会在下次执行的时候尝试重新编译,如果编译通过,则继续执行,编译失败则报错。
这就是为什么两个过程单独执行时不会报错。
那么,为什么两个过程放到一起执行就会报错,即使尝试重新编译也无效呢。这是由于导致过程P_INSERT_T失效的过程就在调用P_INSERT_T过程的匿名块中。在将匿名块提交给Oracle时,Oracle对里面每个过程的状态进行了检查,由于导致P_INSERT_T失效的P_RECREATE过程还没有执行,这时候,所有过程的状态都是VALID,于是Oracle记录下来过程的信息准备到直接运行。但是调用P_RECREATE过程后,由于T表被删除重建,P_INSERT_T的状态发生变化,但是Oracle对过程P_INSERT_T的检查已经完成,因此在尝试直接运行P_INSERT_T的代码的时候发现P_INSERT_T的状态已经发生变化,因此,这里报错ORA-04068,同样的道理,即使对P_INSERT_T进行了重新编译,Oracle在执行时发现检查时的代码已经发生了变化,仍然会报错,即使这个时候存储过程的状态已经时VALID了。
而采用动态SQL不会报错的原因就更容易理解了,由于采用动态SQL,Oracle将编译是进行的操作推迟到运行时进行,也就是说,Oracle会在调用P_RECREATE 之后,调用P_INSERT_T过程之前对P_INSERT_T进行检查并重新编译,因此,采用动态SQL不会报错。
【好文共分享】关于ora-04065和ora-04068的原理解释相关推荐
- 千万别让这些举动断送了你的职业前程-好文共分享
假设你不向自己的同事敞开心扉.那么你根本无法建立一个强大的职业网络,可是这当中的分寸非常不好拿捏.由于表露不当的话会对你的职业生涯造成毁灭性的影响. 分享自己哪些方面是正确的?以什么方式分享是正确的? ...
- 三角形的几何公式大全_椰岛数学:超全高中数学公式记忆表(文末分享PDF)
点击蓝字关注我们 椰岛数学,做自己喜欢的数学 椰 岛 数 学 期 待 您 的 关 注 距高考还有33天>>>> 阅读推荐甭找了!干货全在这儿1. ...
- 从文档分享看互联网重塑教育
进入2014年,在线教育宛如万马奔腾一般迅速火起来!从YY高调"挖角"新东方老师,BAT等巨头先后收购相关公司进行战略布局,传统K12教育机构集体发力.一时间,在线教育领域发展如火 ...
- 怎么把cad做的图分享给别人_在线协同文档分享后,别人只能看却不能写怎么办?...
在这个远程办公方式盛行的时代,越来越多的办公软件开始蜂拥而至,而小编最近发现一款简单而又好用的协作办公软件--石墨文档,这款软件支持多人协作,对云端的文档或表格进行有效的编辑,同时还支持多人同时编辑同 ...
- 引用 好文共赏:hao123站长李兴平的成功史
引用 陈若栋 的 好文共赏:hao123站长李兴平的成功史 这是一个尘封的收购.2004年8月31日,百度宣布以1190万人民币和4万股股票成功收购Hao123网址之家.据百度副总裁梁冬回忆:此次收购 ...
- wps多人协作后怎么保存_在线协同文档分享后,别人只能看却不能写怎么办?
在这个远程办公方式盛行的时代,越来越多的办公软件开始蜂拥而至,而小编最近发现一款简单而又好用的协作办公软件--石墨文档,这款软件支持多人协作,对云端的文档或表格进行有效的编辑,同时还支持多人同时编辑同 ...
- 在线文档分享平台技术实现探讨
最近在研究在线文档分享平台,不经意间又发现了几个网站(除百度文库外),好像大多数网站都是基于flash阅读的,网上也能下载到一些实现的代码! 在线文档分享平台: http://wenku.baidu. ...
- 仿豆丁网仿百度文库在线文档分享源码(全套和全部转换工具后台)
仿豆丁.百度文库.360doc.道客巴巴文档在线网站,好用的文档分享平台,带转换工具,带自动转换后台.本系统不绑定服务器,可以自由使用 该文档为在线共享系统,用户上传普通的OFFICE.txt.pdf ...
- [CTO札记]BaiDu无视版权推文档分享与Google竞争,无疑引火烧身
BaiDu最近推出了一个新产品:文档分享平台,此举应是应对其竞争对手Google'全球获取1000万本书籍数字化'之举. 然而,与Google采用购买版权的方式不同的是,BaiDu是让用户自由上传的方 ...
最新文章
- fastJson反序列化异常,JSONException: expect ‘:‘ at 0, actual =
- C++ Primer 5th笔记(chap 16 模板和泛型编程)定义
- CSS 自由缩放 resize属性
- 阿里云云盾·Web应用防火墙 获“2018网络安全创新产品(技术)评选”一等奖
- flex弹性布局学习总结
- Jvisualvm简单使用教程
- ubuntu16.04修改鼠标按键功能
- NISP第一讲信息安全和网络空间安全
- 双三次插值matlab代码
- 符合功能安全要求的动态测试工具-TESSY
- BUUCTF刷题笔记
- gnome硬盘分析_使用Gnome磁盘工具轻松备份还原硬盘
- 论文阅读:efficient and available in-memory KV-store with hybrid erasurecod and repli
- xbox sdk_因此,您只是获得了Xbox Xbox。 怎么办?
- My english words
- Incorrect result size: expected 1, actual 2
- 丹江口计算机学校,丹江口中专学校计算机网络技术寒假实习
- 制造企业信息化时代——SaaS系统下沉,移动端上升
- 推荐几个牛逼的 iOSer 号
- 操作系统原理_田丽华(6)进程同步