大佬教程收集整理的这篇文章主要介绍了删除触发后的Oracle …如何避免变异表(ORA-04091)?,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
documents dOCMentStatusHistory status +---------+ +--------------------+ +----------+ | docID | | docStatusHistoryID | | statusID | +---------+ +--------------------+ +----------+ | ... | | docID | | ... | +---------+ | statusID | +----------+ | ... | +--------------------+
可能很明显,但值得一提的是,文档的当前状态是输入的最后一个状态历史记录.
系统性能缓慢但肯定会降低,我建议将上述结构更改为:
documents dOCMentStatusHistory status +--------------+ +--------------------+ +----------+ | docID | | docStatusHistoryID | | statusID | +--------------+ +--------------------+ +----------+ | currStatusID | | docID | | ... | | ... | | statusID | +----------+ +--------------+ | ... | +--------------------+
通过这种方式,我们可以将文档的当前状态放在应有的位置.
由于遗留应用程序的构建方式,我无法更改旧应用程序上的代码以更新文档表上的当前状态.
在这种情况下,我不得不为我的规则打开一个例外以不惜一切代价避免触发器,因为我无法访问遗留应用程序代码.
我创建了一个触发器,每次将新状态添加到状态历史记录时都会更新文档的当前状态,并且它就像魅力一样.
但是,在一个模糊且很少使用的情况下,需要删除最后的状态历史记录,而不是简单地添加新的状态历史记录.所以,我创建了以下触发器:
create or replace trigger trgD_History after delete on documentStatusHistory for each row currentStatusid number; begin SELEct statusID into currentStatusID from documentStatusHistory where docStatusHistoryID = (SELEct max(docStatusHistoryID) from documentStatusHistory where docID = :old.docID); update documentos set currStatusID = currentStatusID where docID = :old.docID; end;
那就是我得到臭名昭着的错误ORA-04091.
我明白为什么我收到此错误,即使我将触发器配置为AFTER触发器.
问题是,我无法看到解决此错误的方法.我已经在网上搜索了一段时间,到目前为止找不到任何有用的东西.
我们正在使用oracle 9i.
>包含密钥集合的包(在本例中为docID).临时表也可以
>初始化集合的before语句触发器
>行级触发器,使用已更改的每个docID填充集合
>一个after语句触发器,它迭代集合并执行实际的updatE
所以像
CREATE OR replaCE PACKAGE pkg_document_status AS TYPE typ_changed_docIDs IS table OF documentos.docID%type; changed_docIDs typ_changed_docIDs := new typ_changed_docIDs (); <<other methods>> END; CREATE OR replaCE trigGER trg_init_collection BEFORE deletE ON documentStatusHistory BEGIN pkg_document_status.changed_docIDs.delete(); END; CREATE OR replaCE trigGER trg_populate_collection BEFORE deletE ON documentStatusHistory FOR EACH ROW BEGIN pkg_document_status.changed_docIDs.extend(); pkg_document_status.changed_docIDs( pkg_document_status.changed_docIDs.count() ) := :old.docID; END; CREATE OR replaCE trigGER trg_use_collection AFTER deletE ON documentStatusHistory BEGIN FOR i IN 1 .. pkg_document_status.changed_docIDs.count() LOOP <<fix the current status for pkg_document_status.changed_docIDs(i) >> END LOOP; pkg_document_status.changed_docIDs.delete(); END;
以上是大佬教程为你收集整理的删除触发后的Oracle …如何避免变异表(ORA-04091)?全部内容,希望文章能够帮你解决删除触发后的Oracle …如何避免变异表(ORA-04091)?所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。