`

解决ORA-04091行触发器中访问变异表的难题

 
阅读更多

核心思路就是:在第一次插入时保存值到包变量中,第二次插入时不再读取表本身,转而读取包变量,可以成功解决这类难题。

在工作中,需要为各个BOM的每个ITEM依次自动编号,不同BOM的ITEM的SEQ_NUMBER列都要 按1.2.3…自动生成序号。
第一次,我这样写,

CREATE OR REPLACE TRIGGER TR_BOM_AUTONUMBER_SEQNUMBER
BEFORE INSERT
ON BOM 
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
DECLARE
    tmpVar number;
BEGIN
    tmpVar := 0;
   SELECT GREATEST(nvl(Max(to_number(SEQ_NUMBER)),0), Count(*)) + 1 INTO tmpVar FROM BOM Where BOMID=:New.BOMID;
   :NEW. SEQ_NUMBER:= nvl(tmpVar,1);
END TR_BOM_AUTONUMBER_SEQNUMBER;

由于Insert操作会修改表数据,所以Insert…Select插入多行数据时,会报ORA-04091: table string.string is mutating, trigger/function may not see it错误,原因在于插入第2条数据时表已修改不能再访问。

查阅了很多文章,有提示在其中使用 PRAGMA AUTONOMOUS_TRANSACTION来保证每行插入动作为自治事务。但实际上,经过我的测试,虽然DML不会出错,但实际SEQ_NUMBER全部为1,没有达到依次自动编号的目的。

经过多次试验后,我使用保存于包中的索引表保存各个BOM的最大SEQ_NUMBER,可以防止BOM之间及用户之间的并发冲突。

核心思路就是:在第一次插入时保存值到包变量中,第二次插入时不再读取表本身,转而读取包变量,可以成功解决这类难题。

详细代码如下:

CREATE OR REPLACE PACKAGE BOM_AUTONUMBER
IS
TYPE t_MAX_SEQNUMBER is table of number INDEX BY PLS_INTEGER;
v_MAX_SEQNUMBER t_MAX_SEQNUMBER;
end BOM_AUTONUMBER;
/
CREATE OR REPLACE TRIGGER TR_BOM_AUTONUMBER_SEQNUMBER
BEFORE INSERT
ON BOM 
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
DECLARE
    vNumber number;
    vBOMID number;
BEGIN
    vNumber:= 0;
    vBOMID:= :New.BOMID;
    if not BOM_AUTONUMBER.v_MAX_SEQNUMBER.EXISTS(vBOMID) then
        SELECT GREATEST(nvl(Max(to_number(SEQ_NUMBER)),0), Count(*)) INTO vNumber FROM BOM Where ITEM = vBOMID;
        BOM_AUTONUMBER.v_MAX_SEQNUMBER(vBOMID) := nvl(vNumber, 0);
    end if;
    BOM_AUTONUMBER.v_MAX_SEQNUMBER(vBOMID) := BOM_AUTONUMBER.v_MAX_SEQNUMBER(vBOMID) + 1;
   :NEW.SEQ_NUMBER := BOM_AUTONUMBER.v_MAX_SEQNUMBER(vBOMID);
END TR_BOM_ AUTONUMBER_SEQNUMBER;
/
分享到:
评论

相关推荐

    ORACLE8I数据库应用EXP工具时ORA-06553报错的解决方法.pdf

    ORACLE8I数据库应用EXP工具时ORA-06553报错的解决方法 摘要:本文主要解决ORACLE 8I数据库应用EXP工具时ORA-06553报错的问题,分析出现问题的原因,并提供了正确的解决方法和措施。 知识点1:Oracle 8I数据库EXP...

    Drop goldengate用户时报ORA-00604 ORA-20782 ORA-06512问题解决

    ### 解决Drop Goldengate 用户时报ORA-00604 ORA-20782 ORA-06512问题 #### 一、问题背景与现象 在进行Oracle数据库管理过程中,经常会遇到需要删除用户的场景。当尝试执行`drop user goldengate cascade;`命令时,...

    ora-00604错误解决方法

    ora-00604 错误 解决 方法 ora-00604 错误 解决 方法 ora-00604 错误 解决 方法 ora-00604 错误 解决 方法 ora-00604 错误 解决 方法ora-00604 错误 解决 方法

    Oracle 11gr2连Oracle 19c 报ORA-28040 ORA-01017解决方法.pdf

    这篇文章主要讲述了在Oracle 11g R2客户端尝试连接Oracle 19c服务端时,遇到了两个特定的错误:ORA-28040和ORA-01017,以及如何解决这些问题。 ORA-28040错误是因为客户端和数据库服务器在版本兼容性上存在不匹配。...

    如何解决ORACLE11G里面ORA-24247 网络访问被访问控制列表 (ACL) 拒绝 错误

    ### 如何解决Oracle 11G中的ORA-24247网络访问被访问控制列表 (ACL) 拒绝错误 #### 背景 在处理Oracle 11G数据库时,可能会遇到ORA-24247错误,该错误通常出现在尝试通过网络访问数据库资源时。这一错误是由于访问...

    解决ora-04031共享内存问题

    解决ora-04031共享内存问题解决ora-04031共享内存问题解决ora-04031共享内存问题解决ora-04031共享内存问题

    ORACLE ORA-00132 ORA-00214

    在Oracle数据库管理过程中,遇到ORA-00132和ORA-00214这类错误时,往往意味着数据库配置或启动过程中出现了问题。下面将对这两个错误进行详细解析,并给出相应的解决方案。 #### 二、ORA-00132: Syntax Error or ...

    使用工具IMPDP导入数据时ORA-39002、ORA-39070错误排查

    在使用Oracle Data Pump工具IMPDP(Import Data Pump)进行数据导入的过程中,可能会遇到ORA-39002和ORA-39070等错误。本文将针对这些错误的排查方法进行详细介绍,帮助用户理解问题的原因及解决策略。 ### 错误...

    ORA-12541 TNSno listener 的解决方案

    ORA-12541 TNSno listener 的解决方案 ORA-12541 TNSno listener 的解决方案

    oracle重启报错ORA-00702解决办法

    ORA-00702错误信息表明数据库实例试图访问一个尚未完全初始化的数据文件或控制文件。这可能是由于数据库在不正常的情况下关闭,例如突然断电、系统崩溃或者人为错误导致的。 **Windows系统下的解决步骤** 1. **检查...

    Oracle数据库发生ORA-04031错误原因浅析及处理.pdf

    Oracle数据库发生ORA-04031错误原因浅析及处理 Oracle数据库是甲骨文公司提供的...本文通过对ORA-04031错误的分析和解决方法的介绍,旨在帮助读者更好地理解Oracle数据库中的ORA-04031错误,并提供了实用的解决方法。

    离线误删空间文件导致的ORA-01033及ORA-01145问题的解决办法

    ### 离线误删空间文件导致的ORA-01033及ORA-01145问题的解决办法 #### 概述 在Oracle数据库管理过程中,偶尔会遇到因误操作导致的数据文件出现问题的情况,例如误删除数据文件或者数据文件损坏等。这些问题可能会...

    如何处理错误ORA-29275:部分多字节字符

    在Oracle数据库操作过程中,用户可能会遇到一个特定的错误提示——ORA-29275:部分多字节字符。这一错误通常出现在执行查询`SELECT * FROM V$SESSION`时。该错误的出现意味着在查询结果中存在一些多字节字符(通常是...

    解决ORA-01033 ORACLE 正在初始化或关闭

    ### 解决ORA-01033:Oracle正在初始化或关闭 #### 背景与问题解析 在Oracle数据库管理中,遇到ORA-01033错误是较为常见的问题之一,该错误通常出现在数据库启动或关闭的过程中。ORA-01033错误的全称是“ORA-01033:...

    Oracle 10g启动后报ORA-16038错误的解决方法

    ### Oracle 10g启动后报ORA-16038错误的解决方法 #### 错误概述 在启动Oracle 10g数据库时遇到ORA-16038错误,该错误通常与归档日志操作有关。具体错误信息为: ``` ORA-16038: log 1 sequence #230 cannot be ...

    关于创建oracle 连接时报以下错误,ORA-01017 ORA-02063

    在创建Oracle数据库连接时遇到的错误ORA-01017和ORA-02063涉及到用户认证问题以及Oracle数据库版本之间的差异处理。ORA-01017错误表示用户名或密码无效,登录被拒绝,而ORA-02063则通常表示在Oracle数据库之间进行...

    Oracle_ORA-12518故障_处理

    本文旨在详细介绍ORA-12518错误的成因、常见表现形式以及具体的故障排查方法,以帮助读者在实际工作中能够更高效地解决这一问题。 #### 目的 本文旨在探讨如何接近并解决ORA-12518/TNS-12518错误,并提供详细的...

    oracle网络配置(listener_ora-sqlnet_ora-tnsnames_ora).mht

    oracle网络配置(listener_ora-sqlnet_ora-tnsnames_ora).mht

    Oracle12cRAC数据库 出现ora-12520, ora-12516

    通过上述分析和建议,可以有效地解决Oracle12cRAC数据库中出现的ora-12520和ora-12516问题。关键在于合理调整连接参数、优化应用程序的连接管理策略以及确保监听器配置正确无误。实施这些改进措施后,可以显著提高...

Global site tag (gtag.js) - Google Analytics